【问题标题】:Collapsing select groups折叠选择组
【发布时间】:2019-05-10 14:48:26
【问题描述】:

我正在尝试找到一种更快的方法来迭代折叠数据框中的选定组。我目前正在遍历收购、日期和变量。如果可能的话,我想把它矢量化。

给定一组 id [1,2],我想获取 id 2 的所有值,并将其添加到 id1。此外,我想在此之后从数据集中删除 id2。

生成要调整的数据

dates <- c("Q1", "Q2", "Q3", "Q4")
ids <- c(1,2,3,4)
x1 <- seq(from=1, by=1, length=16)
x2 <- seq(from=1, by=2, length=16)
dat <- expand.grid(dates=dates, ids=ids)
dat <- data.frame(dat, x1, x2)

生成要调整的数据

ref <- data.frame(acquirer=c(2,3), acquired=c(1,4))

用于迭代折叠的慢三倍

for(i in 1:nrow(ref)){
  for(j in c("x1", "x2")){
    for(z in c("Q1", "Q2", "Q3", "Q4")){
      dat[dat$ids==ref$acquirer[i] & dat$dates==z, j] <- 
          dat[dat$ids==ref$acquirer[i] & dat$dates==z, j] +
          dat[dat$ids==ref$acquired[i] & dat$dates==z, j]
      dat[dat$ids==ref$acquired[i] & dat$dates==z, j] <- NA
    }
  }
}

【问题讨论】:

    标签: r performance


    【解决方案1】:

    这应该适用于将 2 折叠为 1 的情况:

    library(dplyr)
    dat %>% 
      mutate(ids = if_else(ids == 2, 1, ids)) %>% 
      group_by(ids, dates) %>% 
      summarize(x1 = sum(x1), x2 = sum(x2))
    

    如果有多个重新编码,您可以添加另一个 mutate 或使用 case_when 调用。

    【讨论】:

    • 这个想法可行,谢谢。 case_when 会阻止我不得不遍历 ref 数据吗?你能提供简短的示例代码吗?我还想总结除 id、日期之外的所有变量。有没有办法使用 summarise 这样的 summarise(setdiff(names(dat), c("ids", dates")) = sum(setdiff(names(dat), c("ids", "dates")))
    • 您能否发布一些您正在考虑的应用程序的示例数据?
    • 使用上面的数据,我现在这样做:sumVars &lt;- c("x1", "x2") for(i in 1:nrow(ref)){dat &lt;- dat %&gt;% mutate(id = ifelse(id==ref$acquired[i], ref$acquiree[i], id)) %&gt;% group_by(ids, dates) %&gt;% summarize_at(vars(sumVars), sum, na.rm=T) %&gt;% ungroup()} 但是,这比上面描述的嵌套for循环过程要慢。
    【解决方案2】:

    使用data.table包的方法:

    library(data.table)
    setDT(dat)
    setDT(ref)
    
    #join the acquirer and acquired into a data.table and calculate x1 and x2 values
    acqDat <- dat[dat[ref, on=.(ids=acquirer), allow.cartesian=TRUE],
        on=.(dates, ids=acquired), allow.cartesian=TRUE,
        .(dates, ids=i.ids, x1=x1+i.x1, x2=x2+i.x2)]
    
    #update by reference the updated x1 and x2 values
    dat[, c("x1", "x2") := acqDat[copy(.SD), on=.(dates, ids), .(x1, x2)]]
    

    输出:

        dates ids x1 x2
     1:    Q1   1 NA NA
     2:    Q2   1 NA NA
     3:    Q3   1 NA NA
     4:    Q4   1 NA NA
     5:    Q1   2  6 10
     6:    Q2   2  8 14
     7:    Q3   2 10 18
     8:    Q4   2 12 22
     9:    Q1   3 22 42
    10:    Q2   3 24 46
    11:    Q3   3 26 50
    12:    Q4   3 28 54
    13:    Q1   4 NA NA
    14:    Q2   4 NA NA
    15:    Q3   4 NA NA
    16:    Q4   4 NA NA
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 2018-08-02
      • 1970-01-01
      • 2016-11-25
      相关资源
      最近更新 更多