【问题标题】:Filter data.table with another data.table with different column names使用具有不同列名的另一个 data.table 过滤 data.table
【发布时间】:2019-03-19 23:52:49
【问题描述】:

我有这个数据集:

library(data.table)    
dt <- data.table(
  record=c(1:20),
  area=rep(LETTERS[1:4], c(4, 6, 3, 7)), 
  score=c(1,1:3,2:3,1,1,1,2,2,1,2,1,1,1,1,1:3),
  cluster=c("X", "Y", "Z")[c(1,1:3,3,2,1,1:3,1,1:3,3,3,3,1:3)]
)

我已经使用这篇文章中的解决方案来创建这个摘要:

dt_summary = 
  dt[ , .N, keyby = .(area, score, cluster)
      ][ , {
        idx = frank(-N, ties.method = 'min') == 1
        NN = sum(N)
        .(
          cluster_mode = cluster[idx],
          cluster_pct = 100*N[idx]/NN,
          cluster_freq = N[idx],
          record_freq = NN
        )
      }, by = .(area, score)]
dt_score_1 <- dt_summary[score == 1]
setnames(dt_score_1, "area", "zone")

我想使用来自dt_score_1 的结果根据区域/区域和集群/集群模式过滤dt。所以在一个新的 data.table 中,从dt 中提取的唯一行应该属于集群 X,对于区域 D,它们应该是集群 Z 等。

【问题讨论】:

标签: r filter data.table subset


【解决方案1】:

如果我对问题的理解正确,这是dtdt_score_1 与条件area = zone, cluster = cluster_mode 的合并。

dt[dt_score_1, on = .(area = zone, cluster = cluster_mode)]

#     record area score cluster i.score cluster_pct cluster_freq record_freq
#  1:      1    A     1       X       1   100.00000            2           2
#  2:      2    A     1       X       1   100.00000            2           2
#  3:      7    B     1       X       1    66.66667            2           3
#  4:      8    B     1       X       1    66.66667            2           3
#  5:     11    C     2       X       1   100.00000            1           1
#  6:     12    C     1       X       1   100.00000            1           1
#  7:     14    D     1       Z       1    80.00000            4           5
#  8:     15    D     1       Z       1    80.00000            4           5
#  9:     16    D     1       Z       1    80.00000            4           5
# 10:     17    D     1       Z       1    80.00000            4           5
# 11:     20    D     3       Z       1    80.00000            4           5

有关join-as-filter的更详细说明,请参阅@Frank发布的以下链接

Perform a semi-join with data.table

【讨论】:

  • 作为参考,这种类型的问题称为“连接”。上述解决方案是使用 area = zone 和 cluster = cluster_mode 作为连接键将 dt 右连接到 dt_score_1。
  • 谢谢。在我看来,它是一个过滤器/子集,因为我真正需要的是这样的:dt[dt_score_1[,c("zone","cluster_mode")], on = .(area = zone, cluster = cluster_mode)]
  • 是的,我猜从data.table 作者的语法相似性来看,右连接也类似于子集。
  • 如果您只想要来自dt 的列,我发现最干净的解决方案是这样的:dt[dt_score_1, on = .(area = zone, cluster = cluster_mode), .SD, .SDcols = names(dt)],这意味着您不需要输入两次列名。
  • x[i] 与过滤器的小差异(在我链接的 hadley 的半连接问题中突出显示): i 的每一行在结果中都有一行,因此来自 i 的不匹配行留下了带有 NA 的行非连接列(除非 nomatch=0);和来自 i 的重复行分别显示。此外,您会得到您可能不想要的 i 列。
猜你喜欢
  • 2023-03-27
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多