编写函数来分析数据帧中的子集

时间:2011-04-11 17:20:00

标签: r

我正在尝试编写一个函数来按特定列聚合或子集数据帧,然后使用特定值计算该数据帧中另一列中值的比例。

具体来说,我的数据框的相关部分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))

2 个答案:

答案 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