首页 > 解决方案 > 在多个数据框之间找到匹配的值组合?r

问题描述

我正在尝试对 r 中多个数据帧的值的匹配组合进行子集化。

我的第一个数据集看起来像这样

head(df_1)
  BCluster ACluster Total_tim ttransfer
1        0        0      955.      1   
2        0       15     3060       0   
3        0       36     2433       1   
4        0       47     2518.      1.5 
5        0       51     1122.      0.15
6        0       67      750       1   

我的第二个数据集看起来像这样

head(df_2)

  BCluster ACluster Total_tim ttransfer
1        5        5     1739.         0
2        5       11     2842          0
3        5       12     4661          0
4        5       27     2913          0
5        5       29     3748.         0
6        5       42     2035          0

第三个看起来像这样

head(df_3)
  BCluster ACluster Total_tim ttransfer
1        0        0     6544          2
2        0       11     2834          1
3        0       15     2159          2
4        0       24     4658          1
5        0       29     5740.         1
6        0       31     2724          2

所有三个数据集都是 ID 列“Bcluster”和“Acluster”的组合。对于这三个数据帧,我想保留每个数据帧的 Bcluster 和 Acluster 的重叠组合并删除其他的

例如,因为在 df_2 中没有 Bcluster=0 和 Acluster=0 的组合。Bcluster=0 和 Acluster=0 组合仅出现在 df_1 和 df_3 的第一行,因此我希望将它们全部从每个数据帧中删除。

我希望是否有人可以帮助我编写此逻辑。

样本数据

 dput(head(df_1))
structure(list(BCluster = c(0L, 0L, 0L, 0L, 0L, 0L), ACluster = c(0L, 
15L, 36L, 47L, 51L, 67L), Total_tim = c(955.25, 3060, 2433, 2518.5, 
1122.4, 750), ttransfer = c(1, 0, 1, 1.5, 0.15, 1)), row.names = c(NA, 
-6L), groups = structure(list(BCluster = 0L, .rows = structure(list(
    1:6), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", 
"list"))), row.names = 1L, class = c("tbl_df", "tbl", "data.frame"
), .drop = TRUE), class = c("grouped_df", "tbl_df", "tbl", "data.frame"
))
dput(head(df_2))
structure(list(BCluster = c(5L, 5L, 5L, 5L, 5L, 5L), ACluster = c(5L, 
11L, 12L, 27L, 29L, 42L), Total_tim = c(1739.31818181818, 2842, 
4661, 2913, 3748.33333333333, 2035), ttransfer = c(0, 0, 0, 0, 
0, 0)), row.names = c(NA, -6L), groups = structure(list(BCluster = 5L, 
    .rows = structure(list(1:6), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1L, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))



> dput(head(df_3))
structure(list(BCluster = c(0L, 0L, 0L, 0L, 0L, 0L), ACluster = c(0L, 
11L, 15L, 24L, 29L, 31L), Total_tim = c(6544, 2834, 2159, 4658, 
5739.5, 2724), ttransfer = c(2, 1, 2, 1, 1, 2)), row.names = c(NA, 
-6L), groups = structure(list(BCluster = 0L, .rows = structure(list(
    1:6), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", 
"list"))), row.names = 1L, class = c("tbl_df", "tbl", "data.frame"
), .drop = TRUE), class = c("grouped_df", "tbl_df", "tbl", "data.frame"
))




标签: rdataframe

解决方案


让我构建一些数据来展示

df1 <- data.frame(a=c(1,2,3), b=c(1,2,3), dat=c(1,2,3))
df2 <- data.frame(a=c(1,4,4), b=c(1,5,5), dat=c(4,5,6))
df3 <- data.frame(a=c(1,6,6), b=c(1,7,7), dat=c(7,8,9))

这给了你例如

> df1
  a b dat
1 1 1   1
2 2 2   2
3 3 3   3

现在的关键思想是您定义一个唯一的链接键,例如从列ab

my.key <- function(x) paste(x, collapse='-')
df1$key <- apply(df1[,c('a','b')],1,FUN=my.key)
df2$key <- apply(df2[,c('a','b')],1,FUN=my.key)
df3$key <- apply(df3[,c('a','b')],1,FUN=my.key)

这给了你例如

> df1
  a b dat key
1 1 1   1 1-1
2 2 2   2 2-2
3 3 3   3 3-3

现在您可以加入数据并仅保留记录。唯一匹配的键:

df <- data.frame(key=merge(merge(df1, df2, by='key'), df3, by='key')$key)

它现在包含所有 3 个数据集中的记录的键,这只是第一个:

> df
  key
1 1-1

不,您可以使用新的转向表作为过滤原始集的设备,并返回转向表中的那些记录,从而返回所有数据集中的记录:

merge(df1, df, by='key')
merge(df2, df, by='key')
merge(df3, df, by='key')

哪个产量

> merge(df1, df, by='key')
  key a b dat
1 1-1 1 1   1

> merge(df2, df, by='key')
  key a b dat
1 1-1 1 1   4

> merge(df3, df, by='key')
  key a b dat
1 1-1 1 1   7

推荐阅读