【问题标题】:How do I add an .x and .y suffix to all duplicate variables after the join?如何在加入后为所有重复变量添加 .x 和 .y 后缀?
【发布时间】:2022-01-11 03:24:09
【问题描述】:

我最初使用的是 dplyr::left_join(),但它没有我想要的 match = "first" 参数在 plyr::join 中可用。现在的问题是我剩余的代码有 .x 和 .y 用于重复变量,所以我不能只使用 janitor::clean_names()。

让您了解我在说什么:

id <- c(1, 2, 3, 4, 5)
name1 <- c("a", "b", "c", "d", "e")
name2 <- c("k", "l", "m", "n", "o")
name3 <- c("u", "v", "w", "x", "y")
name4 <- c("z", "a", "b", "c", "d")

df <- data.frame(id, name1, name2, name3, name4)

id <- c(1, 2, 3, 4, 5)
name1 <- c("f", "i", "j", "k", "l")
name2 <- c("p", "q", "r", "s", "t")
name3 <- c("z", "a", "b", "c", "d")
name5 <- c("z", "a", "b", "c", "d")
df2 <- data.frame(id, name1, name2, name3, name5)

library(plyr)

df_join <- plyr::join(df, df2, by=c("id"), type="left", match="first")

我想把重复的变量(name1、name2、name3)变成如下:

右侧:name1.x、name2.x、name3.x 左侧:name1.y、name2.y、name3.y

我该怎么做呢? janitor::clean_names() 似乎只为左侧变量添加“_2”。

【问题讨论】:

  • 可能是df %&gt;% left_join(df2, by = 'id') %&gt;% group_by(id) %&gt;% slice_head()?
  • @jpdugo17 slice_head() 只是为我输出观察结果。如果我加入多个列怎么办?
  • 我怀疑group_by(id, id2)

标签: r join dplyr plyr


【解决方案1】:

您仍然可以使用dplyr::left_join。要模仿plyr::join 的行为,只需将右侧数据框中重复的ids 转换为NAs 或在左侧数据框的id 列中找不到的任何其他值。例如,

library(dplyr)

df2 %>% 
  mutate(id = replace(id, duplicated(id), NA_integer_)) %>% 
  left_join(df, ., by = "id", suffix = c(".y", ".x"))

输出

  id name1.y name2.y name3.y name4 name1.x name2.x name3.x name5
1  1       a       k       u     z       f       p       z     z
2  2       b       l       v     a       i       q       a     a
3  3       c       m       w     b       j       r       b     b
4  4       d       n       x     c       k       s       c     c
5  5       e       o       y     d       l       t       d     d

这两个数据框是

> df
  id name1 name2 name3 name4
1  1     a     k     u     z
2  2     b     l     v     a
3  3     c     m     w     b
4  4     d     n     x     c
5  5     e     o     y     d
> df2
  id name1 name2 name3 name5
1  1     f     p     z     z
2  2     i     q     a     a
3  3     j     r     b     b
4  4     k     s     c     c
5  5     l     t     d     d
6  1   XXX   XXX   XXX   XXX

这个应该适用于您想要加入的任意数量的列(只要您指定它们)。

libaray(dplyr)

by <- c("id1", "id2")
df2 %>%                                    # v-v------------------- Not a typo. You need two commas here.
  mutate(across(!!by) %>% `[<-`(duplicated(.), , value = NA)) %>% 
  left_join(df, ., by = by, suffix = c(".y", ".x"))

两个数据框

> df
  id1 id2 name1 name2 name3 name4
1   1   5     a     k     u     z
2   2   4     b     l     v     a
3   3   3     c     m     w     b
4   4   2     d     n     x     c
5   5   1     e     o     y     d
> df2
  id1 id2 name1 name2 name3 name5
1   1   5     f     p     z     z
2   2   4     i     q     a     a
3   3   3     j     r     b     b
4   4   2     k     s     c     c
5   5   1     l     t     d     d
6   3   3   XXX   XXX   XXX   XXX

输出

  id1 id2 name1.y name2.y name3.y name4 name1.x name2.x name3.x name5
1   1   5       a       k       u     z       f       p       z     z
2   2   4       b       l       v     a       i       q       a     a
3   3   3       c       m       w     b       j       r       b     b
4   4   2       d       n       x     c       k       s       c     c
5   5   1       e       o       y     d       l       t       d     d

【讨论】:

  • 如果我按两列加入怎么办?
  • 嗨@hy9fesh,查看更新。
【解决方案2】:
library(dplyr)

id <- c(1, 2, 3, 4, 5)
name1 <- c("a", "b", "c", "d", "e")
name2 <- c("k", "l", "m", "n", "o")
name3 <- c("u", "v", "w", "x", "y")
name4 <- c("z", "a", "b", "c", "d")

df <- data.frame(id, name1, name2, name3, name4)

id <- c(1, 1, 3, 3, 5)
name1 <- c("f", "i", "j", "k", "l")
name2 <- c("p", "q", "r", "s", "t")
name3 <- c("z", "a", "b", "c", "d")
name5 <- c("z", "a", "b", "c", "d")
df2 <- data.frame(id, name1, name2, name3, name5)

#not desired result
df %>% left_join(df2, by = 'id')
#>   id name1.x name2.x name3.x name4 name1.y name2.y name3.y name5
#> 1  1       a       k       u     z       f       p       z     z
#> 2  1       a       k       u     z       i       q       a     a
#> 3  2       b       l       v     a    <NA>    <NA>    <NA>  <NA>
#> 4  3       c       m       w     b       j       r       b     b
#> 5  3       c       m       w     b       k       s       c     c
#> 6  4       d       n       x     c    <NA>    <NA>    <NA>  <NA>
#> 7  5       e       o       y     d       l       t       d     d

df_join <- plyr::join(df, df2, by=c("id"), type="left", match="first")
df_join 
#>   id name1 name2 name3 name4 name1 name2 name3 name5
#> 1  1     a     k     u     z     f     p     z     z
#> 2  2     b     l     v     a  <NA>  <NA>  <NA>  <NA>
#> 3  3     c     m     w     b     j     r     b     b
#> 4  4     d     n     x     c  <NA>  <NA>  <NA>  <NA>
#> 5  5     e     o     y     d     l     t     d     d


df %>% left_join(df2, by = 'id') %>% group_by(id) %>% slice_head() %>% as.data.frame()
#>   id name1.x name2.x name3.x name4 name1.y name2.y name3.y name5
#> 1  1       a       k       u     z       f       p       z     z
#> 2  2       b       l       v     a    <NA>    <NA>    <NA>  <NA>
#> 3  3       c       m       w     b       j       r       b     b
#> 4  4       d       n       x     c    <NA>    <NA>    <NA>  <NA>
#> 5  5       e       o       y     d       l       t       d     d

reprex package 创建于 2022-01-11 (v2.0.1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2017-06-14
    • 1970-01-01
    • 2013-02-04
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    相关资源
    最近更新 更多