使用另一个列名不同的data.table对data.table进行筛选

3

我有这个数据集:

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。因此,在一个新的数据表中,从dt中取出的仅属于集群X的A区域行,应该属于集群Z的D区域等。


1
也许相关:https://dev59.com/CmMk5IYBdhLWcg3wyw0U - Frank
1个回答

5
如果我正确理解题意,这是将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发布的链接

使用data.table执行半连接


参考资料,这种问题被称为“连接(join)”。上述解决方案是使用区域(area) = 区域模式(zone)和聚类(cluster) = 聚类模式(cluster_mode)作为连接键对dt和dt_score_1进行正确连接(right join)。 - Scott Ritchie
谢谢。在我看来,这是一个过滤器/子集,因为我实际需要的是这样的东西:dt[dt_score_1[,c("zone","cluster_mode")], on = .(area = zone, cluster = cluster_mode)]。 - Chris
1
是的,我猜测从语法相似性来看,“data.table”的作者们也认为右连接与子集类似。 - IceCreamToucan
1
如果你只想要dt中的列,我找到了最简洁的解决方案,就像这样:dt[dt_score_1, on = .(area = zone, cluster = cluster_mode), .SD, .SDcols = names(dt)] 这意味着你不需要两次输入列名。 - Scott Ritchie
2
x[i]与filter存在小差异(在我链接的hadley半连接问题中突出显示):i的每一行都会在结果中得到一行,因此未匹配的i行将为非连接列留下NA行(除非nomatch = 0);并且i的重复行会单独显示。此外,您还会获得可能不需要的i列。 - Frank
值得注意的是,您可以在data.table调用中添加nomatch = 0以过滤掉i中没有匹配项的行。话虽如此,子集操作也会在未找到项目的地方留下NAs,例如vec <- c(a=1,b=2,c=3); vec[c("b","d")] - Scott Ritchie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接