我有一个数据框,看起来像下面的示例(这里的数据框包含针对每个回合,条件和处理的两个模拟):
df <- data.frame(Sim=c(1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2),Round=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2),Condition=c('A1','A1','A2','A2','A1','A1','A2','A2','B1','B1','B2','B2','B1','B1','B2','B2','A1','A1','A2','A2','A1','A1','A2','A2','B1','B1','B2','B2','B1','B1','B2','B2'),Treatment=c(1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2),Output=c(3,2.5,2.1,1.9,2.8,2.3,2.0,1.6,2.6,2.7,1.3,1.2,2.4,2.3,1,1.1,2,1.3,1.3,0.9,2,2.1,2.1,1.2,2,1.7,1.2,1,2,1.3,0.5,0.4))
条件包含四个级别:A1,A2,B1,B2。
现在,我想操纵此数据框,以便获得A2在A1上针对每个模拟,回合,条件产生的 Output 减少量(%)(1-(A2 / A1) B1(1-(B2 / B1)上的B2也是如此。
我们应该获得与此类似的新dtaframe(此处的“新输出”不是基于数据帧):
Round New condition Treatment Newoutput
1 1-(A2/A1) 1 0.3
1 1-(A2/A1) 1 0.24
...
1 1-(B2/B1) 2 0.5
1 1-(B2/B1) 2 0.56
...
2 1-(A2/A1) 1 0.43
2 1-(A2/A1) 1 0.23
...
2 1-(B2/B1) 1 0.4
2 1-(B2/B1) 1 0.5
...
我一直在尝试split
原始数据帧,但是不确定如何处理它。我还尝试通过使用transform
直接在数据框上进行操作。到目前为止没有成功。
在此先感谢您的帮助。
答案 0 :(得分:1)
我们可以首先在split
上Output
Condition
,然后交替选择1
和2
的值,并使用{{1 }}
mapply
或者如果您希望将它们作为一个矢量直接输入
lst <- with(df, split(Output, Condition))
mapply(function(x, y) 1-(y/x), lst[c(TRUE, FALSE)], lst[c(FALSE, TRUE)])
# A1 B1
#[1,] 0.3000000 0.5000000
#[2,] 0.2400000 0.5555556
#[3,] 0.2857143 0.5833333
#[4,] 0.3043478 0.5217391
#[5,] 0.3500000 0.4000000
#[6,] 0.3076923 0.4117647
#[7,] -0.0500000 0.7500000
#[8,] 0.4285714 0.6923077
如果数据框的顺序不正确,则可以先排列它们,然后使用上面的
unname(1 - (unlist(lst[c(FALSE, TRUE)])/unlist(lst[c(TRUE, FALSE)])))
#[1] 0.3000000 0.2400000 0.2857143 0.3043478 0.3500000 0.3076923 -0.0500000
# 0.4285714 0.5000000 0.5555556 0.5833333 0.5217391 0.4000000 0.4117647
# 0.7500000 0.6923077
或者,如果水平不固定,则可以手动重新排列
df <- df[order(df$Condition), ]
如果还有更多级别,您可以做
df <- df[order(match(df$Condition, c("A1", "A2", "B1", "B2", "C1", "C2"))), ]