如何用两个表的数据为Subject Id匹配所有对应Visit Name
生成受试者与访视的所有组合(笛卡尔积)
你有两个单列表,分别存储受试者ID和访视名称,需要生成每个受试者对应所有访视的完整组合,也就是两个表的笛卡尔积。以下是几种可行的解决方案:
方法1:使用tidyr::crossing(推荐,最简洁)
crossing函数专门用于生成多个向量/数据框的所有可能组合,直接传入两个tibble即可:
library(tibble) library(tidyr) # 修正原代码中的语法错误(Subject Id最后一项多了括号) subjects <- tibble("Subject Id" = c("1-1", "1-2", "1-3")) visits <- tibble("Visits" = c("a", "b", "c")) # 生成所有组合 all_combinations <- crossing(subjects, visits) all_combinations
输出结果:
# A tibble: 9 × 2 `Subject Id` Visits <chr> <chr> 1 1-1 a 2 1-1 b 3 1-1 c 4 1-2 a 5 1-2 b 6 1-2 c 7 1-3 a 8 1-3 b 9 1-3 c
方法2:基础R的expand.grid
如果不想加载额外包,可以用基础R的expand.grid生成组合,再转成tibble:
library(tibble) subjects <- tibble("Subject Id" = c("1-1", "1-2", "1-3")) visits <- tibble("Visits" = c("a", "b", "c")) # 生成组合并转成tibble all_combinations <- as_tibble(expand.grid( `Subject Id` = subjects$`Subject Id`, Visits = visits$Visits, stringsAsFactors = FALSE )) # 按受试者ID排序,和示例一致 all_combinations <- all_combinations[order(all_combinations$`Subject Id`), ] rownames(all_combinations) <- NULL # 清除自动生成的行名 all_combinations
方法3:用dplyr::full_join加临时键
通过给两个表添加一个相同的临时列,再做全连接,最后删除临时列:
library(tibble) library(dplyr) subjects <- tibble("Subject Id" = c("1-1", "1-2", "1-3")) %>% mutate(temp = 1) visits <- tibble("Visits" = c("a", "b", "c")) %>% mutate(temp = 1) all_combinations <- full_join(subjects, visits, by = "temp") %>% select(-temp) %>% # 删除临时列 arrange(`Subject Id`) # 排序 all_combinations
为什么普通merge不适用?
普通的merge()函数默认是内连接,需要两个表有匹配的键值才会合并,而你需要的是所有可能的组合(笛卡尔积),因此需要用上述专门生成全组合的方法。
内容的提问来源于stack exchange,提问作者user21366945
相关产品推荐
相关产品推荐

