使用apply来跨行和列进行计算

时间:2012-01-31 17:35:36

标签: r matrix dataframe apply

我一直在努力寻找使用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列和几千行。

有没有人对我有一些提示?
非常感谢您的帮助。

3 个答案:

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