【问题标题】:How does this unique/filtering syntax work?这种独特/过滤语法如何工作?
【发布时间】:2021-08-12 21:10:09
【问题描述】:

我在 R 中创建了以下 data.table:

> DT
    ID num code
 1:  b 1   C1
 2:  b 1   C1
 3:  b 1   C1
 4:  b 1   C1
 5:  b 1     
 6:  b 3     
 7:  b 3   C1
 8:  a 3   C2
 9:  a 3   C3
10:  a 3   C3
11:  a 3     
12:  c 4   C3

其中空值是空字符串""。然后我运行指令

res <- DT[, .(agg_code = unique(code)[!(code == "")]), .(ID, num)]

导致

> res
   ID num agg_code
1:  b   1       C1
2:  b   1         
3:  b   1     <NA>
4:  b   1     <NA>
5:  b   3       C1
6:  a   3       C2
7:  a   3       C3
8:  a   3         
9:  c   4       C3

我的问题是:这个命令实际上在做什么?我知道它是按 ID 和 num 分组的,我不明白 unique(code)[!(code == "")] 是如何工作的。他们正在删除一些行,但他们也保留一些"" 并创建一些&lt;NA&gt;。这里发生了什么?

为了完整起见,DT 由以下人员创建

DT = data.table(
  ID = c("b","b","b", "b","b", "b","b","a","a","a","a", "c"),
  num = c(1,1,1,1,1,3,3,3,3,3,3,4),
  code = c("C1", "C1","C1","C1", "", "","C1", "C2", "C3", "C3","", "C3")
)

【问题讨论】:

    标签: r data.table filtering grouping unique


    【解决方案1】:

    FWIW 我会以不同的方式编写代码:

    res <- DT[nzchar(code), TRUE, by=.(ID, num, agg_code=code)]
    

    优点:

    1. 只需预先在非空code 上运行一次过滤器,而不是在每个组中运行它
    2. by= 为您处理unique(code) 逻辑。

    注意事项:

    1. 您示例中的代码仍将返回ID/num 对,其中有no 个非空代码;在我的方法中,通过首先过滤,这些对会丢失。
    2. nzchar(code)!(code == "") 不同 NA 输入 -- 请注意 nzchar(NA)TRUE!(NA == "")NA。如果这是一个问题,您可以将其更改为nzchar(code, keepNA = TRUE)。请注意,""NA(又名 NA_character_)不同。
    3. j 中的 TRUE 是一次性的。如果更清楚,我们也可以写unique(DT[nzchar(code)], by=c('ID', 'num', 'code'))。我们必须在输出中重命名code->agg_code

    【讨论】:

      【解决方案2】:

      这三个命令应该澄清:

      DT[ ID == "b" & num == 1, ]
      #    ID num code
      # 1:  b   1   C1
      # 2:  b   1   C1
      # 3:  b   1   C1
      # 4:  b   1   C1
      # 5:  b   1     
      
      DT[ ID == "b" & num == 1, .(x = unique(code))]
      #     x
      # 1: C1
      # 2:   
      
      DT[ ID == "b" & num == 1, .(x = code == "")]
      #        x
      # 1: FALSE
      # 2: FALSE
      # 3: FALSE
      # 4: FALSE
      # 5:  TRUE
      

      简而言之,unique 得到 2 个值,code == "" 给了我们 5 个值,所以第二个命令的输出被回收了。

      【讨论】:

        猜你喜欢
        • 2014-08-26
        • 2015-02-09
        • 2021-10-02
        • 1970-01-01
        • 1970-01-01
        • 2018-08-07
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        相关资源
        最近更新 更多