我一直在努力寻找使用apply的解决方案,但我无法找到我需要的确切内容。我是来自Excel的新R用户,需要计算与控件观察的百分比差异。一个真实的样本数据框如下所示:
site <- c(rep(1, 10), rep(2,10), rep(3,10))
element <-rep(c("ca", "Mg", "K"), 10)
control <- seq(from= 1,to=60, by=2)
BA01 <- seq(from= 31,to=90, by=2)
BA02 <- seq(from= 21,to=80, by=2)
BA03 <- seq(from= 101,to=160, by=2)
mydf <- data.frame(site, element, control, BA01, BA02,BA03)
其中BA01至BA03是不同的测试,将与对照进行比较。
我想做的就是做一个像这样的公式: ((BA01对照)/对照)* 100
并计算每个测试列(BA01-BA03)和数据框中的每一行。在Excel中,我可以复制并粘贴网站和元素列以及标题BA01-BA03,在单元格C2中键入公式,然后根据需要将公式向右拖动,然后根据需要向下拖动并得到我的结果。在R我很难得到相同的结果。我已经尝试过申请,但无法让它发挥作用。基本上,我希望将Site和Element作为第1列和第2列,然后使用BA01,BA02和BA03作为列名称的公式结果。可能它没有什么区别,但我的真实数据框将有超过130列和几千行。
有没有人对我有一些提示?
非常感谢您的帮助。
丹
答案 0 :(得分:1)
如果我理解正确:
cbind(mydf[1:2],sapply(mydf[-(1:3)],function(x) 100*(x-mydf[[3]])/mydf[[3]]))
site element BA01 BA02 BA03
1 1 ca 3000.00000 2000.00000 10000.0000
2 1 Mg 1000.00000 666.66667 3333.3333
3 1 K 600.00000 400.00000 2000.0000
4 1 ca 428.57143 285.71429 1428.5714
5 1 Mg 333.33333 222.22222 1111.1111
...
答案 1 :(得分:1)
试试这个:
cbind(mydf[1:2], 100 * mydf[4:6] / mydf$control - 100)
前5行输出是:
site element BA01 BA02 BA03
1 1 ca 3000.00000 2000.00000 10000.0000
2 1 Mg 1000.00000 666.66667 3333.3333
3 1 K 600.00000 400.00000 2000.0000
4 1 ca 428.57143 285.71429 1428.5714
5 1 Mg 333.33333 222.22222 1111.1111
答案 2 :(得分:0)
怎么样:
pdiff <- function(x,y) (x-y)/y*100
BAcols <- subset(mydf,select=c(BA01,BA02,BA03))
这个subset
对于小数据框是可读的,但是如果你想要规范化的行数很多,你会想要使用数字范围选择这些列,即mydf[,-(1:3)]
(删除前三列)或mydf[,4:ncol(mydf)]
(将第4列保留到最后)。
cbind(mydf[,1:2],sweep(BAcols,1,mydf$control,pdiff))
或
with(mydf,data.frame(site,element,sweep(BAcols,1,control,pdiff)))