2017-06-05 41 views
0

琛特定的列我有一个表,看起来像这样:(注意:这只是一个局部的表,我真正的表有qresult_#和trial_#的几个列)使用循环

Contract FA  NAAR q trial_1 qresult_1 trial_2 qresult_2 
CM300  9746 47000 0.5 0.4352  d   0.7534  l 
UL350  80000  0 0.01 0.9287  l   0.2336  l 
RAD34  50000 10000 0.943 0.6161  d   0.1545  d 

表是使用for循环计算的,所以列trial_i和qresult_i为我所希望的列创建。这是一个用于创建表的代码:

testdata <- data.frame(Contract = as.character(c("CM300","UL350","RAD34")), 
        FA = as.numeric(as.character(c("9746","80000","50000"))), 
        NAAR = as.numeric(as.character(c("47000","0","10000"))), 
        q = as.numeric(as.character(c("0.50","0.01","0.943")))) 

trialmax <- 2 
for(i in 1:trialmax){ 
    trial <- runif(3, min = 0, max = 1) 
    testdata[ , paste0("trial_", i)] <- trial 
    testdata[ , paste0("qresult_", i)] <- ifelse(trial >= testdata$q, "l", "d") 
} 

这里是我的问题:我想总结的FA列和标有“d”的所有合同的NAAR栏,标有“L”的所有合同每个试验单独。因此对于试验_1,'d'的FA将是59746,'d'的NAAR将是57000,'l'的FA将是80000,并且'l'的NAAR将是0.并且对于每次试验重复这一点。最终结果将是每个试验的四个值。

我还没有找到允许我成功运行它的代码。我希望每个试验的预期输出为四个值。也许是这个样子,重复每次试验:

trial1_d_fa <- if(trial_1 = 'd') {sum(testdata$FA)} 
trial1_l_fa <- if(trial_1 = 'l') {sum (testdata$FA)} 
trial1_d_naar <- if(trial_1 = 'd') {sum(testdata$NAAR)} 
trial1_l_naar <- if(trial_1 = 'l') {sum(testdata$NAAR)} 

我与得到一个for循环工作努力,因为在代码中的列名称使用我定义。我是R新手,因此非常感谢任何提示!

编辑:更新

低于bouncyball建议的代码工作在我的测试数据,但是当我用它在我的真实的数据,我得到了以下错误消息:

Error in match.names(clabs, names(xi)) : 
names do not match previous names 

展望通过这个网站,我可以看到这是rbind()函数的问题。我试图转换列名以匹配我的数据,但我仍然得到相同的错误。

这是我的数据集head(data)的开始。任何建议表示赞赏!

Contract FA  NAAR  q  trial_1 qresult_1 trial_2 qresult_2  
CM20002U 10000 4902.34 0.0255 0.7921  l  0.5182  l 
CM20051U 45700 28788.81 0.0121 0.0083  d  0.0707  l 
CM20076U 50000 20824.54 0.1054 0.5616  l  0.0915  d 
+0

u能显示预期的输出 – akrun

+0

我已经编辑我原来的职位,以显示这一点,并在那里我被卡住了。谢谢 – Karly

回答

0

下面是使用lapplyby功能的方式。我们需要调用重复到do.call('rbind', ...)因为在列表中两个条目从lapply导致:

trial_max <- 2 

do.call('rbind', 
     do.call('rbind', 
       lapply(paste0('qresult_', 1:trial_max), function(q){ 
        by(testdata, testdata[,q], FUN = function(d) 
        data.frame('id' = q, 
           'val' = unique(d[,q]), 
           'sum_FA' = sum(d$FA), 
           'sum_NAAR' = sum(d$NAAR), 
           stringsAsFactors = FALSE)) 
}))) 

     id val sum_FA sum_NAAR 
1 qresult_1 d 59746 57000 
2 qresult_2 d 59746 57000 
3 qresult_1 l 80000  0 
4 qresult_2 l 80000  0 

使用lapply,我们遍历qresult_i列,那么我们使用by函数的函数应用于testdata分裂由相应的qresult_i列中的值确定。最后,我们将结果存储在data.frame中。

结果存储在data.frame,这应该可以很容易地子集,并让你感兴趣的值。

+0

有没有办法做到这一点,当我有不止两次审判?我希望能够通过数百次试验来运行这个测试,因此手动输入每个qresult列名称将非常繁琐。 – Karly

+0

每列的名称是否一致?例如。 'qresult_1','qresult_2',...,'qresult_n'? – bouncyball

+0

是的,这是正确的。这些列被命名为trial_1,qresult_1,trial_2,qresult_2,trial_3,qresult_3等...... – Karly