3

適用関数のすべての可能性を使用する方法を説明する満足のいくチュートリアルが見つかりません。私はまだ初心者ですが、これは多くの場合便利で、コードを大幅に簡素化できます。これが私の例です...次のようなデータフレームがあります:

> head(p01)
   time key dwell
1   8.13   z  0.00
3   8.13   x  1.25
5   9.38   l  0.87
7  10.25   x  0.15
9  10.40   l  1.13
11 11.53   x  0.45

それをRに入れます:

p01 <- structure(list(time = c(8.13, 8.13, 9.38, 10.25, 10.4, 11.53), 
key = c("z", "x", "l", "x", "l", "x"), dwell = c(0, 1.25, 
0.869, 0.15, 1.13, 0.45)), .Names = c("time", "key", "dwell"), row.names = c(1L, 3L, 5L, 7L, 9L, 11L), class = "data.frame")

ここで、各文字の出現回数を数えて に出力p01$keyp01$occurences、結果が次のようになるようにします。

    time key dwell occurences
1   8.13   z  0.00          1
3   8.13   x  1.25          3
5   9.38   l  0.87          2
7  10.25   x  0.15          3
9  10.40   l  1.13          2
11 11.53   x  0.45          3

私が今それを行う方法は次のとおりです。

p01[p01$key == "l", "occurences"] <- table(p01$key)["l"]
p01[p01$key == "x", "occurences"] <- table(p01$key)["x"]
p01[p01$key == "z", "occurences"] <- table(p01$key)["z"]

...もちろん、これは最善の解決策ではありません。p01$key特に、実際のデータには(16 種類の文字のうちの 1 つ) の可能性が含まれているためです。

その上で、各文字の合計を計算したいdwellので、今やっていることは次のとおりです。

p01[p01$key == "l", "total_dwell"] <- tapply(p01$dwell, p01$key, sum)["l"]
p01[p01$key == "x", "total_dwell"] <- tapply(p01$dwell, p01$key, sum)["x"]
p01[p01$key == "z", "total_dwell"] <- tapply(p01$dwell, p01$key, sum)["z"]

取得するために:

    time key dwell total_dwell
1   8.13   z  0.00        0.00
3   8.13   x  1.25        1.85
5   9.38   l  0.87        2.00
7  10.25   x  0.15        1.85
9  10.40   l  1.13        2.00
11 11.53   x  0.45        1.85

私は過去6時間、グーグルで数冊の本を読んでいます。エレガントなソリューションや包括的なチュートリアルへのリンクを本当に感謝します。私のソリューションは明らかに機能していますが、このような問題を回避しなければならないのは初めてではなく、スクリプト ファイルがばかげているように見え始めています!

4

4 に答える 4

10

データセットが巨大な場合は、data.table を試してください。

library(data.table)
DT <- data.table(p01)
DT[,occurences:=.N,by=key]
DT[,total_dwell:=sum(dwell),by=key]

    time key dwell occurences total_dwell
1:  8.13   z 0.000          1       0.000
2:  8.13   x 1.250          3       1.850
3:  9.38   l 0.869          2       1.999
4: 10.25   x 0.150          3       1.850
5: 10.40   l 1.130          2       1.999
6: 11.53   x 0.450          3       1.850

参照による割り当ての 2 行は、次のように組み合わせることができます。

DT[, `:=`(occurences = .N, total_dwell = sum(dwell)), by=key]
于 2013-04-22T15:04:18.500 に答える
6

私は使用しますplyr

res = ddply(p01, .(key), transform, 
                           occurrences = length(key), 
                           total_dwell = sum(dwell))
res
   time key dwell occurrences total_dwell
1  9.38   l 0.869           2       1.999
2 10.40   l 1.130           2       1.999
3  8.13   x 1.250           3       1.850
4 10.25   x 0.150           3       1.850
5 11.53   x 0.450           3       1.850
6  8.13   z 0.000           1       0.000

この後、表は でアルファベット順にソートされることに注意してくださいkeyorderに頼ることができますtime

res[order(res$time),]
   time key dwell occurrences total_dwell
3  8.13   x 1.250           3       1.850
6  8.13   z 0.000           1       0.000
1  9.38   l 0.869           2       1.999
4 10.25   x 0.150           3       1.850
2 10.40   l 1.130           2       1.999
5 11.53   x 0.450           3       1.850
于 2013-04-22T15:00:20.903 に答える
3

ここは使いたくないと思いますapplytable頻度を取得してmatchから、頻度をテーブルに割り当てるために使用する方法は次のとおりです。

freq <- as.data.frame( table(p01$key) )
    # Var1 Freq
#1    l    2
#2    x    3
#3    z    1

p01$occurences <- freq[ match(p01$key , freq[,1] ) , 2 ]
p01
#   time key dwell occurences
#1   8.13   z 0.000          1
#3   8.13   x 1.250          3
#5   9.38   l 0.869          2
#7  10.25   x 0.150          3
#9  10.40   l 1.130          2
#11 11.53   x 0.450          3

私が知る限り、plyrソリューションに対するこの方法の唯一の利点は、データフレームの元の順序が保持されることです。ただし、関数でこれを指定できるかどうかはわかりませんddply(おそらく指定できます!)。

于 2013-04-22T15:00:13.350 に答える
2

この問題は、tapply で自然に解決できます。これらは、オブジェクト p01 に追加するのではなく、新しいオブジェクト p01.summary を作成することに注意してください。別のコード行でそれを修正できます

p01.summary = with(p01, cbind(occurences=table(key),total.dwell=tapply(dwell,key,sum)))

また

p01.summary = with(p01, do.call(rbind,tapply(dwell,key,function(KEY){
   data.frame(occurence=length(KEY),total.dwell= sum(KEY))
}) ))
于 2013-04-22T15:52:23.500 に答える