我有一个包含7列的数据框(wc2):
cm5 cm10 cm15 cm20 cm25 cm30 run_time
1 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060 0
2 0.4084525 0.4028010 0.3617393 0.2595060 0.1294412 0.1220099 2
3 0.4087809 0.4042515 0.3711077 0.3119956 0.2241836 0.1290348 4
4 0.4088547 0.4045780 0.3732053 0.3218224 0.2611785 0.1720426 6
5 0.4088770 0.4046887 0.3739936 0.3255557 0.2739738 0.2081264 8
6 0.4088953 0.4047649 0.3744183 0.3273794 0.2798225 0.2273250 10
对于每一行(run_time),我想首先平均第一列,然后是第一列和第二列,然后是第一列,第二列和第三列,依此类推,直到第6列。平均结果应该在新列或新数据框中(我不介意)。 我使用以下代码完成了它:
wc2$dia10 <- wc2$cm5
wc2$dia20 <- rowMeans(wc2[c("cm5", "cm10")])
wc2$dia30 <- rowMeans(wc2[c("cm5", "cm10", "cm15")])
wc2$dia40 <- rowMeans(wc2[c("cm5", "cm10", "cm15", "cm20")])
wc2$dia50 <- rowMeans(wc2[c("cm5", "cm10", "cm15", "cm20", "cm25")])
wc2$dia60 <- rowMeans(wc2[c("cm5", "cm10", "cm15", "cm20", "cm25", "cm30")])
根据我对R的基本知识,我有一个更好的方法,但我无法弄清楚如何。特别是当我有更多的列时。 我查看了R&#34中的数据帧的总和和增加数量的答案。但无法理解或将其应用于我的数据。
感谢您的帮助
答案 0 :(得分:6)
您可以将Reduce
与accumulate = TRUE
参数一起使用,如下所示,
sapply(Reduce(c, 1:(ncol(df)-1), accumulate = TRUE)[-1], function(i) rowMeans(df[i]))
或者获得准确的输出,
setNames(data.frame(df[1],sapply(Reduce(c, 1:(ncol(df)-1),accumulate = TRUE)[-1], function(i)
rowMeans(df[i]))), paste0('dia', seq(from = 10, to = ncol(df[-1])*10, by = 10)))
或者@ A5C1D2H2I1M1N2O1R2T1在评论中建议,
do.call(cbind, setNames(lapply(1:6, function(x) rowMeans(df[1:x])),
paste0("dia", seq(10, 60, 10)))
两者都给予,
dia10 dia20 dia30 dia40 dia50 dia60 1 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060 2 0.4084525 0.4056268 0.3909976 0.3581247 0.3123880 0.2806583 3 0.4087809 0.4065162 0.3947134 0.3740339 0.3440639 0.3082257 4 0.4088547 0.4067164 0.3955460 0.3771151 0.3539278 0.3236136 5 0.4088770 0.4067829 0.3958531 0.3782787 0.3574178 0.3325359 6 0.4088953 0.4068301 0.3960262 0.3788645 0.3590561 0.3371009
或者将其添加到原始数据框中,然后
cbind(df, setNames(lapply(1:6, function(x) rowMeans(df[1:x])),
paste0("dia", seq(10, 60, 10))))
答案 1 :(得分:2)
以下是使用apply
和cumsum
的替代方法。使用rowMeans
几乎肯定是可取的,但是这种方法一次完成计算。
setNames(data.frame(t(apply(dat[1:6], 1, cumsum) / 1:6)),
paste0("dia", seq(10, 60, 10)))
dia10 dia20 dia30 dia40 dia50 dia60
1 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060 0.1221060
2 0.4084525 0.4056268 0.3909976 0.3581247 0.3123880 0.2806583
3 0.4087809 0.4065162 0.3947134 0.3740339 0.3440639 0.3082257
4 0.4088547 0.4067164 0.3955460 0.3771151 0.3539278 0.3236136
5 0.4088770 0.4067829 0.3958531 0.3782787 0.3574178 0.3325359
6 0.4088953 0.4068301 0.3960262 0.3788645 0.3590561 0.3371009
使用更智能的Reduce("+"
和@ alexis-laz建议的累积,我们可以做
mapply("/", Reduce("+", dat[1:6], accumulate = TRUE), 1:6)
或获取具有所需名称的data.frame
setNames(data.frame(mapply("/", Reduce("+", dat[1:6], accumulate = TRUE), 1:6)),
paste0("dia", seq(10, 60, 10)))
下面的丑陋代码遵循相同的想法,没有mapply
setNames(data.frame(Reduce("+", dat[1:6], accumulate = TRUE)) /
rep(1:6, each=nrow(dat)), paste0("dia", seq(10, 60, 10)))