【问题标题】:Removing trailing values per group in data.table删除 data.table 中每组的尾随值
【发布时间】:2021-06-29 13:13:42
【问题描述】:

我想删除 data.table 中所有等于 0 的最后分组观察值(以下示例中的 Value 列)。我想保留中间 0 值。任何帮助表示赞赏。

library(data.table)

df <- structure(list(Country = c("NL", "NL", "NL", "NL", "DE", "DE", 
"DE", "GB", "GB"), Value = c(1, 2, 3, 0, 3, 0, 1, 2, 0), Value2 = c(100, 
200, 400, 500, 200, 200, 100, 800, 600)), row.names = c(NA, -9L
), class = c("data.table", "data.frame"))

   Country Value Value2
1:      NL     1    100
2:      NL     2    200
3:      NL     3    400
4:      NL     0    500
5:      DE     3    200
6:      DE     0    200
7:      DE     1    100
8:      GB     2    800
9:      GB     0    600

期望的输出:

   Country Value Value2
1:      NL     1    100
2:      NL     2    200
3:      NL     3    400
4:      DE     3    200
5:      DE     0    200
6:      DE     1    100
7:      GB     2    800

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    为了完整起见,这里有一个使用last().Idata.table 解决方案:

    df[!df[, last(.I[last(Value) == 0]), by = Country]$V1]
    
       Country Value Value2
    1:      NL     1    100
    2:      NL     2    200
    3:      NL     3    400
    4:      DE     3    200
    5:      DE     0    200
    6:      DE     1    100
    7:      GB     2    800
    

    df[, last(.I[last(Value) == 0]), by = Country] 将索引.I 返回到要删除的行的原始数据集df

       Country V1
    1:      NL  4
    2:      GB  9
    

    警告

    这种方法以及迄今为止发布的其他答案只会删除 一个 尾随零,但不会删除多个尾随零。

    删除多个尾随零

    如果一个国家/地区序列的末尾有多个尾随零,则可以使用rle() 函数:

    library(data.table)
    df2[, {
      r <- rle(Value)
      if (last(r$values) == 0)
        head(.SD, -last(r$lengths))
      else
        .SD
    }, Country]
    
        Country Value Value2
     1:      NL     1    100
     2:      NL     2    200
     3:      NL     3    400
     4:      DE     3    200
     5:      DE     0    200
     6:      DE     1    100
     7:      GB     2    800
     8:      FR     1    100
     9:      FR     0    200
    10:      FR     3    300
    

    数据

    df2 <- fread("Country Value Value2
    NL     1    100
    NL     2    200
    NL     3    400
    NL     0    500
    DE     3    200
    DE     0    200
    DE     1    100
    GB     2    800
    GB     0    600
    FR     1    100
    FR     0    200
    FR     3    300
    FR     0    400
    FR     0    500")
    

    请注意,countryFR 有两个尾随零。

    【讨论】:

      【解决方案2】:

      你可以使用 -

      library(data.table)
      df[, .SD[!(Value == 0 & seq_len(.N) == .N)], Country]
      
      #   Country Value Value2
      #1:      NL     1    100
      #2:      NL     2    200
      #3:      NL     3    400
      #4:      DE     3    200
      #5:      DE     0    200
      #6:      DE     1    100
      #7:      GB     2    800
      

      不执行任何分组功能也可以使用duplicated

      setDT(df)[!(!duplicated(Country, fromLast = TRUE) & Value == 0)]
      

      这可以写成dplyr为-

      library(dplyr)
      
      #1. 
      df %>%
        group_by(Country) %>%
        filter(!(Value == 0 & row_number()== n())) %>%
        ungroup
      
      #2.
      df %>% filter(!(!duplicated(Country, fromLast = TRUE) & Value == 0))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-19
        • 1970-01-01
        • 2019-07-07
        • 1970-01-01
        相关资源
        最近更新 更多