问题描述
我有一个看起来像这样的数据集
I have a data set that looks like that
set.seed(100)
da <- data.frame(exp = c(rep("A", 4), rep("B", 4)), diam = runif(8, 10, 30))
对于数据集中的每一行,我想总结比特定行中的直径大并且包含在"exp"级别中的观察值(直径).为此,我做了一个循环:
For each row in the data set I want to sum up observations (diam) that are bigger than the diam in the specific row and are included in a level "exp".To do that I made a loop:
da$d2 <- 0
for (i in 1:length(da$exp)){
for (j in 1:length(da$exp)){
if (da$diam[i] < da$diam[j] & da$exp[i] == da$exp[j]){
da$d2[i] = da$d2[i] + da$diam[j]}
}
}
lopp正常工作,我得到了结果
The lopp works fine and I got results
exp diam d2
1 A 16.15532 21.04645
2 A 15.15345 37.20177
3 A 21.04645 0.00000
4 A 11.12766 52.35522
5 B 19.37099 45.92347
6 B 19.67541 26.24805
7 B 26.24805 0.00000
8 B 17.40641 65.29445
但是,我的实际数据集远大于该数据集(> 40000行和> 100 exp水平),因此循环非常慢. 我希望可以使用一些功能来简化计算.
However, my real data set is much bigger than that (> 40000 rows and >100 exp levels) so the loop goes very slow. I hope it is possible to use some function to facilitate calculations.
推荐答案
如果您不需要结果中的初始订单,则可以像这样高效地完成它:
If you don't require the initial order in the result you could do it quite efficiently like this:
library(data.table)
setorder(setDT(da), exp, -diam)
da[, d2 := cumsum(diam) - diam, by = exp]
da
# exp diam d2
#1: A 21.04645 0.00000
#2: A 16.15532 21.04645
#3: A 15.15345 37.20177
#4: A 11.12766 52.35522
#5: B 26.24805 0.00000
#6: B 19.67541 26.24805
#7: B 19.37099 45.92347
#8: B 17.40641 65.29445
使用dplyr,那就是:
Using dplyr, that would be:
library(dplyr)
da %>%
arrange(exp, desc(diam)) %>%
group_by(exp) %>%
mutate(d2 = cumsum(diam) - diam)
这篇关于循环以汇总大于R中的主题的观察结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!