在 R 中使用 full_join 处理重复的列
Dealing with duplicated columns using full_join in R
下午好!
我目前正在使用 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)
和表 2:
Name <- c("Martin", "Anna", "Olga", "Boris")
ID <- c("ID6", "ID3", "ID7", "ID4")
PDN <- c(22, 6, 44, 70)
Sum3009 <- c(10, 8, 45, 30)
Sum3110 <- c(9, 6, 30, 20)
table2 <- data.frame(Name, ID, PDN, Sum3009, Sum3110)
我选择了 full_join 运算符,因为它在理论上完美地解决了任务:
table3 <- full_join(table1, table2, by = c("Name", "ID", "PDN"))
一切都是正确的,因为这两个表中所有重复的列都select作为键。
但是,如果我只需要 select 作为特定列名称的键,并选择 full_join,R 将复制在表中重复的列,这不是我所期望的。
table3 <- full_join(table1, table2, by = c("Name", "ID")) #"PDN" was removed
是否可以运行连接特定的列而不是在两个表中全部重复而不得到重复的结果?
预期结果:我想仅使用两个键 (c("Name", "ID")) 从两个表中获得完全连接,其中显示了“PDN”列但在结果部分中没有重复 ( PDN.x 和 PDN.y 不在身边)。
提前致谢!非常感谢任何帮助!
这有帮助吗?与不同顺序的完全连接相同的输出。我没有指定 PDN,但我指定了我想要求和的列,这不包括 PDN。
bind_rows(table1, table2) %>%
group_by(Name, ID) %>%
summarise(across(contains("Sum"), ~sum(.x, na.rm = T)), .groups = "drop")
我还想不出一种方法让 R 将 PDN 列与 Sum 列区别对待,而不给它一些指示它应该像键一样对待 and/or 其他人应该像对待一样值。
编辑 - 这并不优雅,但您可以采用的另一种方法是进行所需的连接,然后“在 post 中修复它。”这里通过重塑 long,从列名中删除任何“.x”或“.y”,过滤第一个非 NA,然后再次转向宽来完成。
但这肯定更糟。 :-)
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
下午好!
我目前正在使用 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)
和表 2:
Name <- c("Martin", "Anna", "Olga", "Boris")
ID <- c("ID6", "ID3", "ID7", "ID4")
PDN <- c(22, 6, 44, 70)
Sum3009 <- c(10, 8, 45, 30)
Sum3110 <- c(9, 6, 30, 20)
table2 <- data.frame(Name, ID, PDN, Sum3009, Sum3110)
我选择了 full_join 运算符,因为它在理论上完美地解决了任务:
table3 <- full_join(table1, table2, by = c("Name", "ID", "PDN"))
一切都是正确的,因为这两个表中所有重复的列都select作为键。
但是,如果我只需要 select 作为特定列名称的键,并选择 full_join,R 将复制在表中重复的列,这不是我所期望的。
table3 <- full_join(table1, table2, by = c("Name", "ID")) #"PDN" was removed
是否可以运行连接特定的列而不是在两个表中全部重复而不得到重复的结果?
预期结果:我想仅使用两个键 (c("Name", "ID")) 从两个表中获得完全连接,其中显示了“PDN”列但在结果部分中没有重复 ( PDN.x 和 PDN.y 不在身边)。
提前致谢!非常感谢任何帮助!
这有帮助吗?与不同顺序的完全连接相同的输出。我没有指定 PDN,但我指定了我想要求和的列,这不包括 PDN。
bind_rows(table1, table2) %>%
group_by(Name, ID) %>%
summarise(across(contains("Sum"), ~sum(.x, na.rm = T)), .groups = "drop")
我还想不出一种方法让 R 将 PDN 列与 Sum 列区别对待,而不给它一些指示它应该像键一样对待 and/or 其他人应该像对待一样值。
编辑 - 这并不优雅,但您可以采用的另一种方法是进行所需的连接,然后“在 post 中修复它。”这里通过重塑 long,从列名中删除任何“.x”或“.y”,过滤第一个非 NA,然后再次转向宽来完成。
但这肯定更糟。 :-)
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