2

私の最後の質問によると、私は新しい所属の質問があります。投稿を編集してそこで質問し、1 週間ほど待ってから、ここでもう一度試してみたいと思います。

今回はより良い例で:

Equip<- c(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,6,6)
Notif <-c(1,1,3,4,2,2,2,5,6,7,9,9,15,10,11,12,13,14,16,17,18,19)
rank <- c(1,1,2,3,1,1,1,1,2,3,1,1,2,1,2,3,1,2,3,4,5,6)
Component <- c("Ventil","Motor","Ventil","Ventil","Vergaser","Vergaser","Bremse",
"Lichtmaschine","Bremse","Lichtmaschine","Bremse","Motor","Lichtmaschine",
"Bremse","Bremse","Motor","Vergaser","Motor","Vergaser","Motor",
"Vergaser","Motor")    

df <- data.frame(Equip,Notif,rank,Component)

Equipは私の件名でありrank、実際の訪問数です。Component探さなければならない主題です。

次のような出力が必要です。

anEquip(subject)が 2 回 (1 回目と 2 回目) 訪問された場合、1 回目と2 回目とみなされたものがある場合は、 1&2 でrankすべてEquipの s を調べます。rankComponent

Equip(subject)すべての sが 3 回 ( rank1 、2 および 3 )訪問した場合、1 、1 、Motor 、1 、2 、Motor 、1 、3 、Motorのように 3 回アップされたリスト Equipがある場合ComponentEquiprankComponentEquiprankComponentEquiprankComponent

Component出力には、True "Motor" のようなの名前が含まれている必要があります。

私はコードを持っていますが、これを使用すると、1 と 2 の訪問、2 と 3 を一緒に比較することができます (2 ランクの装備、3 ランクの装備などのように、ランクで再度分割することはできません。の上)

コードはこれです:

a <- lapply(split(df,df$Equip),function(x){      
ll <- split(x,x$rank)                    
 if(length(ll)>1 )
ii <- intersect(ll[[1]]$Component,ll[[2]]$Component ) ## test intersection
  else 
   ii <- NA
 c(length(ii)> 0 && !is.na(ii),ii)                                              
})
b <- unlist(a)
c <- table(b,b)
rowSums(c)    

うまくいけば、あなたは私を助けることができます. ご不明な点がございましたらお尋ねください。

出力に関する質問と解決方法に応じて、

     Equip Component   V1 idx
1:     1    Ventil  TRUE   3
2:     2        NA  False  1
3:     3        NA  False  3
4:     4        NA  FALSE  2
5:     5        NA  FALSE  3
6:     6        NA  FALSE  6

みたいな感じだけど、簡単ならEquipとidxは必須じゃない

2 ランク装備の場合:

TRUE          FALSE
  0             1

3つのランクを装備する場合:

TRUE          FALSE
 1              2

6 ランク装備の場合:

TRUE          FALSE
 0              1
4

2 に答える 2

2

これがあなたの興味を引くと思う出力です。その使用data.table

まず、次のようdata.tableにあなたからdata.frame dfを作成しkeys = Equip, Componentます。

require(data.table) # load package
# then create the data.table with keys as specified above
# Check that both these columns are already sorted out for you!
dt <- data.table(df, key=c("Equip", "Component"))

次に、特定のランククエリ(2、3など)に必要な出力を提供する関数を作成します。

this.check <- function(idx) {
    chk <- seq(1, idx)
    o <- subset(dt[, all(chk %in% rank), by=c("Equip", "Component")], V1 == TRUE)
    if (nrow(o) > 0) o[, idx:=idx]
}

これは何をしますか?これを実行してみましょうrank=1,2。これを実行するのは次のとおりです。

> this.check(2)
# output
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2

これは、に対して、それぞれwithEquip = 1 and 5があることを示しています(idx = 2で示されます)。@Carlがすでに指摘したように、私はこれの必要性を理解していませんが、列も取得します。必要に応じて、次を使用してこの出力の列名を変更できます。Components = Ventil and Bremserank = 1 and 2V1 = TRUEsetnames

第三に、この関数を使用してクエリを実行ranks=1,2し、次にranks=1,2,3..などを実行します。lapplyこれは、次のように簡単に実行できます。

# Let's run the function for idx = 2 to 6. 
# This will check from rank = 1,2 until rank=1,2,3,4,5,6
o <- lapply(2:6, function(idx) {
    this.check(idx)
})
> o
[[1]]
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2

[[2]]
   Equip Component   V1 idx
1:     1    Ventil TRUE   3

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

それはのためにrank=1,2そしてrank=1,2,3あなたがいくつかを持っていることを示していますComponent。他の人にとっては何もありません= NULL

最後に、bindこれらすべてを一緒に使用rbindして、次のように1つのシングルを取得できdata.tableます。

o <- do.call(rbind, o)
> o
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2
3:     1    Ventil TRUE   3

ここで、idx=2Componentを満たしrank=1,2idx=3はを満たしrank=1,2,3ます。

すべてを一緒に入れて:

this.check <- function(idx) {
    chk <- seq(1, idx)
    o <- subset(dt[, all(chk %in% rank), by=c("Equip", "Component")], V1 == TRUE)
    if (nrow(o) > 0) o[, idx:=idx]
}

o <- do.call(rbind, lapply(2:6, function(idx) {
    this.check(idx)
}))

これがお役に立てば幸いです。

編集:(コメントでの一連の交換の後、これは私が提案する新しいソリューションです。これがあなたが求めているものであることを願っています。)

require(data.table)
dt <- data.table(df, key=c("Equip", "Component"))
dt[, `:=`(e.max=max(rank)), by=Equip]
dt[, `:=`(ec.max=max(rank)), by=c("Equip", "Component")]
setkey(dt, "e.max", "ec.max")
this.check <- function(idx) {
    t1 <- dt[J(idx,idx)]
    t2 <- t1[, identical(as.numeric(seq_len(idx)), as.numeric(rank)), 
              by=c("Equip", "Component")]
    o <- table(t2$V1)
    if (length(o) == 1) 
        o <- c(o, "TRUE"=0)
    o <- c("idx"=idx, o)
}
o <- do.call(rbind, lapply(2:6, function(idx) this.check(idx)))

> o
#      idx FALSE TRUE
# [1,]   2     1    0
# [2,]   3     2    1
# [3,]   4     1    0
# [4,]   5     1    0
# [5,]   6     1    0
于 2013-01-17T13:05:52.223 に答える
0

あなたのデータの配列を列ごとに作成すると、

foo<-cbind(Equip,Notif, rank, Component)
eqp<-1 # later, loop over all values
foo[c( which(  foo[,1]==eqp & (foo[,3]==1 | foo[,3]==2) ) ),4]
[1] "Ventil" "Motor"  "Ventil"

それらの結果をフィードtableし、count ==2 の項目を抽出します

明らかに、2 回表示されるアイテムはすべて、必要なものです。
これは、ツールが好きddplyで、これをはるかにきれいに行うため、使用することをお勧めする答えではありませんが、元の値aggregateのループを想定して、これがあなたが求めている答えであることを確認したいと思います。 eqpEquip

于 2013-01-16T20:30:24.210 に答える