子集数据 table 由名称包含特定子字符串的列中的所有唯一条目组成,其他条目用 NA 填充

Subset data table by all unique entries in columns whose name contain a certain substring, fill with NA for other entries

我有一个数据 table,我想复制或子集化变量名称包含特定子字符串的变量中的所有唯一观察值。我可以想出一种使用 for 循环笨拙地完成它的方法,但这似乎会破坏数据 table.

的实用性和速度

例如:

library(data.table)
library(dplyr)
dt <- setDT(tibble(a_ID = c(1, 1, 2, 11, 2),
                   b = c('x','y','z','z', 'x'),
                   b_ID = c('XY','XY','XY','XY', 'XY'),
                   d = 1:5))

我想从这里做的是将名称包含 'ID' 的所有列子集化,return 仅包含每列中的唯一条目,因为这将导致列具有不同每个观察值的数量,其余的用 NA 填充。

也就是说,我想要return以下内容:

subset_dt <- setDT(tibble(a_ID = c(1,2,11),
                          b_ID = c('XY', NA,NA)))

data.table 功能是否可行?

我们可能会得到 unique 个元素,然后 replace duplicatedNA

library(data.table)
dt[, lapply(.SD, unique), .SDcols = patterns("_ID$")][,
    lapply(.SD, \(x) replace(x, duplicated(x), NA))]

-输出

    a_ID   b_ID
   <num> <char>
1:     1     XY
2:     2   <NA>
3:    11   <NA>

unique

的另一个选项
unique(dt[, .(a_ID, b_ID)])[, lapply(.SD, \(x) fcase(!duplicated(x), x))]
    a_ID   b_ID
   <num> <char>
1:     1     XY
2:     2   <NA>
3:    11   <NA>

或者另一种选择是阻止代码,检查 unique 步骤后的 length 并附加 NA 以固定长度

dt[, {lst1 <- lapply(.SD, unique)
     mx <- max(lengths(lst1))
    lapply(lst1, `length<-`, mx)}, .SDcols = patterns("_ID$")]
    a_ID   b_ID
   <num> <char>
1:     1     XY
2:     2   <NA>
3:    11   <NA>

我们也可以使用 collapse - select 列 (gvr),获取唯一行 (funique),用 [=26 遍历列=], replaceNA

的重复项
library(collapse)
dapply(funique(gvr(dt, "_ID$")), MARGIN = 2, 
   FUN = \(x) replace(x, duplicated(x), NA))
    a_ID   b_ID
   <num> <char>
1:     1     XY
2:     2   <NA>
3:    11   <NA>