2012-06-20 122 views
2

我有一个数据帧df,其中每个主题记录一个数字列表/向量,用于两次重复的测试项目。最有效的方法来替换数据帧中的最低列表值R

subj item rep vec 
s1 1 1 [2,1,4,5,8,4,7] 
s1 1 2 [1,1,3,4,7,5,3] 
s1 2 1 [6,5,4,1,2,5,5] 
s1 2 2 [4,4,4,0,1,4,3] 
s2 1 1 [4,6,8,7,7,5,8] 
s2 1 2 [2,5,4,5,8,1,4] 
s2 2 1 [9,3,2,6,6,8,5] 
s2 2 2 [7,1,2,3,2,7,3] 

对于每个项目,我想找到50%代表1的平均值,然后替换最低编号与0中的rep 2矢量,直到REP2的平均值小于或等于REP1的平均。例如,对于S1 ITEM1:

mean(c(2,1,4,5,8,4,7))*0.5 = 2.1 #rep1 scaled down 
mean(c(1,1,3,4,7,5,3)) = 3.4 #rep2 
mean(c(0,0,0,0,7,5,0)) = 1.7 #new rep2 such that mean(rep2) <= mean(rep1) 

在代表2矢量除去最低号码后,我想关联的REP1和REP2矢量,并执行一些其它少量的算术函数,并将结果附加到另一个(长度初始化)数据帧。现在,我正在用类似于这个伪代码的循环来做这件事:

for subj in subjs: 
    for item in items: 
    while mean(rep2) > mean(rep1)*0.5: 
     rep2 = replace(lowest(rep2),0) 
    newDataFrame[i] = correl(rep1,rep2) 

用循环做这件事似乎真的很低效;在R中,是否有更有效的方法来查找和替换列表/矢量中的最低值,直到平均值小于或等于取决于特定项目的值为止?将相关性和其他结果附加到其他数据框的最佳方法是什么?

附加信息:

>dput(df) 
>structure(list(subj = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L), .Label = c("s1", "s2"), class = "factor"), item = c(1L, 
1L, 2L, 2L, 1L, 1L, 2L, 2L), rep = c(1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L), vec = list(c(2, 1, 4, 5, 8, 4, 7), c(1, 1, 3, 4, 7, 
5, 3), c(6, 5, 4, 1, 2, 5, 5), c(4, 4, 4, 0, 1, 4, 3), c(4, 6, 
8, 7, 7, 5, 8), c(2, 5, 4, 5, 8, 1, 4), c(9, 3, 2, 6, 6, 8, 5 
), c(7, 1, 2, 3, 2, 7, 3))), .Names = c("subj", "item", "rep", 
"vec"), row.names = c(NA, -8L), class = "data.frame") 

我想这个数据帧作为输出(与REP1与REP2相关和REP1 VS新REP2相关)。

subj item origCorrel newCorrel 
s1 1 .80 .51 
s1 2 .93 .34 
s2 1 .56 .40 
s2 2 .86 .79 
+2

如果您可以在您的问题中添加'dput(subjs)'的输出以及此数据集的所需输出,那将会很棒。 – GSee

+0

对不起,你说过“我有一个数据框,里面有数字列表/向量”;我认为这是'subjs'。请提供'data.frame'的'dput' – GSee

+0

您的伪代码与您的叙述有点不一致。我想你想要在伪代码中颠倒不平等。 – Seth

回答

1

摆脱循环的一个典型的策略是让所有的计算是在子集化的数据到自己的函数,然后调用该函数在aggregateapply功能。

two.cors=function(x,ratio=.5) { 
    rep1=unlist(x[1,][['vec']]) 
    rep2=unlist(x[2,][['vec']]) 
    orig.cor=cor(rep1,rep2) 
    while(mean(rep2) > mean(rep1)*ratio) { 
    rep2[ which(rep2==min(rep2[which(!rep2==0)]))]=0 
    } 
    c(orig.cor,wierd.cor=cor(rep1,rep2)) 
} 

我想daply使用,因此得到plyr,本来合计使用或基地*apply功能

library(plyr) 

然后调用函数你的数据集

daply(df,c("subj","item"), .fun=function(x) two.cors(x,ratio=.4)) 

此输出可重新格式化,但我把它留给你,因为我认为你需要额外的统计数据,其中包括two.cors函数

+0

如果我想为two.cors指定一个额外的参数(例如''two.cors = function(x,param)''),我会如何将它添加到''daply()''行? – Amyunimus

+0

我编辑了我的帖子,通过daply将参数传递给two.cors函数。 – Seth