我找不到令人满意的教程,可以解释我如何使用应用函数的所有可能性。我仍然是一个新手,但这通常会派上用场,并显着简化我的代码。所以这是我的榜样...... 我有一个看起来像这样的数据框:
> 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$key
中每个字母的出现次数并将其打印在p01$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个不同字母之一)中包含更多可能性。
最重要的是,我想为每个字母计算总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个小时里,我一直在谷歌上搜索并阅读几本书。真的很感激优雅的解决方案和/或一些综合教程的链接。 我的解决方案显然有效,但这不是我第一次解决这个问题,我的脚本文件开始看起来很荒谬!
答案 0 :(得分: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
按引用分配的两行可以组合如下:
DT[, `:=`(occurences = .N, total_dwell = sum(dwell)), by=key]
答案 1 :(得分: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
请注意,在此之后,该表按字母顺序排列在key
上。您可以使用order
来求助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
答案 2 :(得分:3)
我不认为你想在这里使用apply
。 table
如何获取频率,然后使用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
函数中指定它(可能你可以!)。
答案 3 :(得分:2)
你可以用tapply自然地解决这个问题。 请注意,它们会生成一个新对象p01.summary,而不是添加到您的对象p01。 另一行代码可以修复
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))
}) ))