在R中使用full_join处理重复列

在R中使用full_join处理重复列,r,join,data-manipulation,R,Join,Data Manipulation,下午好 我目前正在使用R处理一个数据操作任务,面临着一个两难的境地 有两个表,我的目标是使用特定键连接这些表 表1: Name <- c("John", "Michael", "Anna", "Boris") ID <- c("ID1", "ID2", "ID3", "ID4") PDN <- c(40, 10, 6,

下午好

我目前正在使用R处理一个数据操作任务,面临着一个两难的境地

有两个表,我的目标是使用特定键连接这些表

表1:

Name <- c("John", "Michael", "Anna", "Boris")
ID <- c("ID1", "ID2", "ID3", "ID4")
PDN <- c(40, 10, 6, 70)
Sum3107 <- c(16, 10, 53, 44)
Sum3108 <- c(16, 8, 50, 43)

table1 <- data.frame(Name, ID, PDN, Sum3107, Sum3108)

Name这有帮助吗?以不同的顺序将输出与完全联接相同。我没有指定PDN,但我指定了要求和的列,这不包括PDN

bind_rows(table1, table2) %>%
  group_by(Name, ID) %>%
  summarise(across(contains("Sum"), ~sum(.x, na.rm = T)), .groups = "drop")
我还想不出一种方法,可以让R将PDN列与Sum列区别对待,而不给它一些指示,表明它应该被视为键和/或其他列应该被视为值


编辑-这并不优雅,但您可以采取的另一种方法是执行所需的连接,然后“在post中修复”。在这里,您可以通过重塑long,从列名中删除任何“.x”或“.y”,过滤第一个非NA,然后再次转宽来完成

但这肯定更糟。:-)

full_join(表1,表2,by=c(“Name”,“ID”))%>%
pivot_更长(-c(名称,ID))%>%
突变(name=name%>%str_remove(“.x |.y”))%>%
过滤器(!is.na(值))%>%
分组依据(名称、ID、名称)%%>%slice(1)%%>%ungroup()%%>%
枢轴(名称从=名称,值从=值)
#一个tibble:6x7
名称ID PDN Sum3009 Sum3107 Sum3108 Sum3110
1 Anna ID3 6 8 53 50 6
2 Boris ID4 70 30 44 43 20
3约翰ID1 40 NA 16 NA
4 Martin ID6 22 10 NA 9
5迈克尔ID2 10 NA 10 8 NA
6 Olga ID7 44 45 NA 30

能否显示您的预期输出?从你的描述我不太明白。你想把PDN从join指令中去掉,但得到相同的结果,这样R就不会在输出中复制该列了吗?我也不这么认为。如果双方都贡献了一个名为
PDN
的列,而该列不在联接条件中,则返回两个列时都会有一个后缀,如
PDN.x
PDN.y
。你想把这两列合并起来吗?可能在连接后使用
?coalesce
?是的,例如,我有两个数据集,其中前27列在两个表中重复。我的目标是只选择4-5个键(重复列)来实现完全连接,因为在大多数情况下都有NAs,但如果我这样做,所有其他重复列都将被复制。
table3 <- full_join(table1, table2, by = c("Name", "ID", "PDN"))
table3 <- full_join(table1, table2, by = c("Name", "ID")) #"PDN" was removed
bind_rows(table1, table2) %>%
  group_by(Name, ID) %>%
  summarise(across(contains("Sum"), ~sum(.x, na.rm = T)), .groups = "drop")
full_join(table1, table2, by = c("Name", "ID")) %>%
  pivot_longer(-c(Name, ID)) %>%
  mutate(name = name %>% str_remove(".x|.y")) %>%
  filter(!is.na(value)) %>%
  group_by(Name, ID, name) %>% slice(1) %>% ungroup() %>%
  pivot_wider(names_from = name, values_from = value)

# A tibble: 6 x 7
  Name    ID      PDN Sum3009 Sum3107 Sum3108 Sum3110
  <chr>   <chr> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1 Anna    ID3       6       8      53      50       6
2 Boris   ID4      70      30      44      43      20
3 John    ID1      40      NA      16      16      NA
4 Martin  ID6      22      10      NA      NA       9
5 Michael ID2      10      NA      10       8      NA
6 Olga    ID7      44      45      NA      NA      30