【问题标题】:Loop to sum up observation greater than subject in R循环总结观察大于R中的主题
【发布时间】:2015-05-20 09:36:16
【问题描述】:

我有一个看起来像这样的数据集

set.seed(100)
da <- data.frame(exp = c(rep("A", 4), rep("B", 4)), diam = runif(8, 10, 30))

对于数据集中的每一行,我想总结大于特定行中直径并包含在级别“exp”中的观察值(直径)。 为此,我做了一个循环:

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 工作正常,我得到了结果

  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 级别),因此循环非常缓慢。 希望可以使用一些函数来方便计算。

【问题讨论】:

    标签: r loops


    【解决方案1】:

    如果您不需要结果中的初始顺序,您可以像这样非常有效地做到这一点:

    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,那就是:

    library(dplyr)
    da %>%
      arrange(exp, desc(diam)) %>%
      group_by(exp) %>%
      mutate(d2 = cumsum(diam) - diam)
    

    【讨论】:

    • 非常好的解决方案。您可能可以通过exp 跳过订购,但输出不会那么好。或者你可以改用keyby = exp
    • @DavidArenburg,谢谢,我想过这个问题,但后来就让它保持原样 - 我认为这不会有太大的不同
    猜你喜欢
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多