【问题标题】:Fill missing values by rolling forward in each group using data.table通过使用 data.table 在每个组中前滚来填充缺失值
【发布时间】:2018-01-29 13:21:58
【问题描述】:

我的目标是通过前滚按组填充缺失值。

虚拟数据

library(data.table)

DT <- structure(list(CLASS = c("A", "A", "A", "A", "A", "A", "B", "B","B"),
VAL = c(NA, 1, NA, NA, 2, NA, 50, NA, 100)),
.Names = c("CLASS", "VAL"),
row.names = c(NA, -9L), class = c("data.table", "data.frame"))

> DT
   CLASS VAL
1:     A  NA
2:     A   1
3:     A  NA
4:     A  NA
5:     A   2
6:     A  NA
7:     B  50
8:     B  NA
9:     B 100

想要的结果

   CLASS VAL
1:     A  NA
2:     A   1
3:     A   1
4:     A   1
5:     A   2
6:     A   2
7:     B  50
8:     B  50
9:     B 100

注意,here 的结果不适用。

1) 这会将第一个非缺失值分配给组中的每个观察值

#1
DT[, VAL:= VAL[!is.na(VAL)][1L] , by = CLASS]
> DT
   CLASS VAL
1:     A   1
2:     A   1
3:     A   1
4:     A   1
5:     A   1
6:     A   1
7:     B  50
8:     B  50
9:     B  50

2) 如果要分配的行仅在i 中过滤为缺失值,则在by 中分组时将无法拾取任何非NA 值。所以结果没有任何改变。

> DT[is.na(VAL), VAL:= VAL[!is.na(VAL)][1L] , by = CLASS]
> DT
   CLASS VAL
1:     A  NA
2:     A   1
3:     A  NA
4:     A  NA
5:     A   2
6:     A  NA
7:     B  50
8:     B  NA
9:     B 100
9:     B  50

3) 使用来自tidyrfill() 的解决方案有效,但不幸的是使用了350 万行和200 万组的真实数据;运行时间约为 6 小时。所以我正在寻找更高效的data.table 解决方案。

> DT <- DT %>% group_by(CLASS) %>% fill(VAL)
> DT
# A tibble: 9 x 2
# Groups:   CLASS [2]
  CLASS    VAL
  <chr>  <dbl>
1 A      NA   
2 A       1.00
3 A       1.00
4 A       1.00
5 A       2.00
6 A       2.00
7 B      50.0 
8 B      50.0 
9 B     100  

【问题讨论】:

    标签: r data.table missing-data


    【解决方案1】:

    您可以使用zoo 包中的na.locf() 函数:

    DT[, VAL:=zoo::na.locf(VAL, na.rm = FALSE), "CLASS"]
    

    【讨论】:

    • fromLast=FALSE 是默认值,因此可以省略。也可以使用na.locf0(VAL)
    • 这真是太棒了!运行时间为 1.2 分钟,而 fill() 运行时间为 6 小时
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2020-11-18
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多