首页 > 解决方案 > 这种独特/过滤语法如何工作?

问题描述

我在 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 == "")]的。他们正在删除一些行,但他们也保留一些""并创建一些<NA>. 这里发生了什么?

为了完整起见,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")
)

标签: rdata.tablefilteringgroupingunique

解决方案


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

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

优点:

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

注意事项:

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

推荐阅读