【问题标题】:Iteratively replace values within a group in a conditional cummin manner以条件 cummin 方式迭代地替换组内的值
【发布时间】:2021-05-16 18:17:36
【问题描述】:

一个超大数据集的子集有两个维度:一个是组ORG,另一个是距离dist,例如,

  1. 第 3 行表示在 15 公里半径范围内(某个坐标)没有 (N=0) 法国公司。
  2. 第 6 行,有一家 (N=1) 成立于 1992 年 (FirstEntry=1992) 的法国公司 (FirstEntry=1992) 在 30 公里半径范围内(到某个坐标)。

我需要高效地生成一个新列FirstEntry2,如下所示:

    ORG dist N FirstEntry FirstEntry2
 1: FRA    5 0         NA          NA
 2: FRA   10 0         NA          NA
 3: FRA   15 0         NA          NA
 4: FRA   20 0         NA          NA
 5: FRA   25 0         NA          NA
 6: FRA   30 1       1992        1992 # the first valid firm A w/in 30km radius
 7: FRA   35 2       1994        1992 # firm A must be earliest w/in 35km as well, so replace this with 1992
 8: FRA   40 2       1994        1992 # the same as previous row
 9: FRA   45 2       1994        1992 # the same as previous row
10: FRA   99 2       1994        1992 # the same as previous row
11: JPN    5 0         NA          NA
12: JPN   10 0         NA          NA
13: JPN   15 0         NA          NA
14: JPN   20 0         NA          NA
15: JPN   25 0         NA          NA
16: JPN   30 0         NA          NA
17: JPN   35 1       1995        1995 # w/in 35km, this is earliest, though afar there's a firm est. in 1992
18: JPN   40 2       1992        1992 # so, FirstEntry2 in this row no need to be replaced
19: JPN   45 2       1992        1992 # the same reason, no replace
20: JPN   99 2       1992        1992 # the same reason, no replace
21: DEU    5 0         NA          NA
22: DEU   10 1       1998        1998 # the first valid firm C, w/in 10km radius
23: DEU   15 2       1999        1998 # this firm C must be earliest w/in 15km as well, so replace this with 1998
24: DEU   20 2       1999        1998 # the same as previous row
25: DEU   25 2       1999        1998 # the same as previous row
26: DEU   30 2       1999        1998 # the same as previous row
27: DEU   35 2       1999        1998 # the same as previous row
28: DEU   40 2       1999        1998 # the same as previous row
29: DEU   45 2       1999        1998 # the same as previous row
30: DEU   99 2       1999        1998 # the same as previous row
# Sorry, there were mistakes when I posted it here at first. (edited)
test <- data.table(ORG = c(rep("FRA", 10), rep("JPN", 10), rep("DEU", 10)),
                   dist = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 99, 
                            5, 10, 15, 20, 25, 30, 35, 40, 45, 99,
                            5, 10, 15, 20, 25, 30, 35, 40, 45, 99), 
                   N = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 2L, 2L, 2L, 
                         0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L,
                         0L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
                   FirstEntry = c(NA, NA, NA, NA, NA, 1992, 1994, 1994, 1994, 1994, 
                                  NA, NA, NA, NA, NA, NA, 1995, 1992, 1992, 1992,
                                  NA, 1998,rep(1999, 8)), 
                   FirstEntry2= c(NA, NA, NA, NA, NA, 1992, 1992, 1992, 1992, 1992, 
                                  NA, NA, NA, NA, NA, NA, 1995, 1992, 1992, 1992,
                                  NA, rep(1998, 9)))

我尝试过类似的方法,但不是想要的结果

test[, FirstEntry2 := shift(FirstEntry), by = .(ORG, cumsum(c(1, +(FirstEntry > shift(FirstEntry) & !is.na(FirstEntry))[-1])))] 

我怎样才能做到正确?非常感谢!

【问题讨论】:

  • 不太确定逻辑,但可能是cummin 问题吗? test[!is.na(FirstEntry) , res := cummin(FirstEntry), by = ORG]
  • @Henrik 。这不是一个直观的例子,对cummin 来说也不是问题,而是我对cummin 所需要的。这背后的逻辑很繁琐:原始数据报告有关公司_i、观察年份、银行分行_j 的列。因为我只需要带有firm_i - 外国银行branchs_j 对的行,所以我计算所有这些公司-分支对的地理距离,并将距离划分为与test[[dist]] 相同的间隔。然后我沿着 dist 间隔计算 #branches 和 min(year)cumsum()。在这一步之后,cumsum(N) 是正确的,而 min(year) 不是,因为.....
  • @Henrik,因为 .... (1) 一家拥有更多分支机构的公司可能更早建立了分支机构为其提供服务,例如#row 17 和 18,就在这里。 (2) 最早的分支机构在 30 公里半径范围内的公司相当于在任何半径范围内都有此分支机构,尽管以后可能会在任何更远的半径范围内建立分支机构,例如 #row 6 和 7。跨度>
  • 请提供一个足够复杂的最小示例。看起来我的代码会给出想要的结果,所以你需要添加它失败的情况。
  • @Henrik 您提供的内容是正确的。谢谢。

标签: r data.table zoo


【解决方案1】:

我想出了一个解决办法,

for (col in names(test)) set(test, which(is.na(test[[col]])), col, value = 9999 )

test[, FirstEntry3 := cummin(FirstEntry), 
      by = .(ORG)]

identical(test$FirstEntry2, test$FirstEntry3)

不!我的大脑没有功能......

【讨论】:

    猜你喜欢
    • 2021-08-15
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 2020-04-30
    • 2018-05-06
    相关资源
    最近更新 更多