我正在尝试编写一个函数来按特定列聚合或子集数据帧,然后使用特定值计算该数据帧中另一列中值的比例。
具体来说,我的数据框的相关部分allmutations如下所示:
gennumber sel
1 -0.00351647088810292
1 0.000728499401888683
1 0.0354633950503043
1 0.000209700229276244
2 6.42307549736376e-05
2 -0.0497259605114181
2 -0.000371856995145525
在每一代(gennumber)中,我想计算“sel”中值大于0.001,介于-0.001和0.001之间,小于-0.001的比例。在整个数据集中,我刚刚这样做:
ben <- allmutations$sel > 0.001 #this is for all generations
bencount <- length(which(ben==TRUE))
totalmu <- length(ben) # #length(ben) = total # of mutants
tot.pben <- bencount/totalmu #proportion
对于gennumber中的每个值执行该操作的最佳方法是什么?此外,是否有一种简单的方法可以获得-0.001 <-0.001范围内的值的比例。 sel&lt; 0.001?我无法弄清楚如何做到这一点,所以我“欺骗”并获取了列的绝对值,只是寻找小于0.001的值。我不禁觉得必须有更好的方法。
感谢您提供的任何帮助,如果我能提供任何澄清,请告诉我。
dput()
数据:
structure(list(gennumber = c(1L, 1L, 1L, 1L, 2L, 2L, 2L), sel = c(-0.00351647088810292,
0.000728499401888683, 0.0354633950503043, 0.000209700229276244,
6.42307549736376e-05, -0.0497259605114181, -0.000371856995145525
)), .Names = c("gennumber", "sel"), class = "data.frame", row.names = c(NA,
-7L))
答案 0 :(得分:0)
您可以将两个逻辑测试与&
结合使用,以便测试-0.001&lt; sel&lt; 0.001你可以写sel > -0.001 & sel < 0.001
以下是使用plyr
的方法:
dat <- read.table(tc <- textConnection("
gennumber sel
1 -0.00351647088810292
1 0.000728499401888683
1 0.0354633950503043
1 0.000209700229276244
2 6.42307549736376e-05
2 -0.0497259605114181
2 -0.000371856995145525"), header = TRUE); close(tc)
library("plyr")
ddply(dat,.(gennumber),summarize,
`sel < -0.001` = sum(sel < -0.001)/length(sel),
`-0.001 < sel < 0.001` = sum(sel > -0.001 & sel < 0.001)/length(sel),
`0.001 < sel` = sum(sel > 0.001)/length(sel))
答案 1 :(得分:0)
对于第一部分,假设您的数据位于dat
,我们首先按gennumber
分割数据:
sdat <- with(dat, split(dat, gennumber))
然后我们编写一个自定义函数来进行你想要的比较
foo <- function(x, cutoff = 0.001) {
sum(x[,2] > cutoff) / length(x[,2])
}
和sapply()
覆盖sdat
sapply(sdat, foo)
给出了:
> sapply(sdat, foo)
1 2
0.25 0.00
这个数据样本。
对于第二部分,我们可以扩展上面的函数foo()
以接受上限和下限并进行计算:
bar <- function(x, upr, lwr) {
sum(lwr < x[,2] & x[,2] < upr) / length(x[,2])
}
其中给出了[显示如何传递额外参数]
> sapply(sdat, bar, lwr = -0.001, upr = 0.001)
1 2
0.5000000 0.6666667