更新数值变量为一组的各行作为最小的子组的

时间:2019-01-31 06:35:22

标签: r data.table

我有一个按3个不同变量和一个测量变量分组的数据列表,如下所示。 ID1 =因数, ID2 =整数, ID3 =数字, varX =数字

ID1 ID2 ID3  varX
A   1   0.1  40.0
A   1   0.8  70.5
A   2   0.7  55.0
A   2   0.8  65.0
A   2   1.0  60.0
B   4   0.2  70.0
B   5   0.6  55.7
C   1   0.1  55.0
C   1   0.3  90.0
C   1   0.9  60.0
C   5   0.8  45.5
C   5   0.9  30.0

我想将 varX 的每个值更新为按ID1和ID2分组的最小值,但也要按按ID3分组的最小值,其中只有ID3值大于或等于当前行的行才能被更新确定最小时被考虑。

例如:对于ID1 = A,ID2 = 2,ID3 = 0.7,varX为最小值55.0、65.0和60.0。而对于ID1 = A,ID2 = 2,ID3 = 0.8,则varX为最小值65.0和60.0。

结果表如下:

ID1 ID2 ID3  varX
A   1   0.1  40.0
A   1   0.8  70.5
A   2   0.7  55.0
A   2   0.8  60.0
A   2   1.0  60.0
B   4   0.2  70.0
B   5   0.6  55.7
C   1   0.1  55.0
C   1   0.3  60.0
C   1   0.9  60.0
C   5   0.8  30.0
C   5   0.9  30.0

我有36,000行这种格式的数据,因此性能相对重要

1 个答案:

答案 0 :(得分:1)

这是一种更为冗长的dplyr方法,可能足够快(1秒即可处理格式中的100万行)。

library(dplyr)
df2 <- df %>%
  tibble::rowid_to_column() %>%   # to use later to put back in original order
  group_by(ID1, ID2) %>%
  arrange(-ID3) %>%   # starting with the largest ID3 within each group and working down...
  mutate(varX2 = cummin(varX)) %>%   # what's the min varX encountered so far?
  ungroup() %>%
  arrange(rowid)   # put back in original order

这是我测试过的虚假数据:

n = 1000000
df <- data_frame(
  ID1 = sample(LETTERS[1:26], size = n, replace = T),
  ID2 = sample(1:100, size = n, replace = T),
  ID3 = sample(0.1*1:10, size = n, replace = T),
  varX = rnorm(n, 50, 30))