【问题标题】:R join data efficiently if one of the columns in the first dataset matches any of the columns in the second dataset如果第一个数据集中的一个列与第二个数据集中的任何列匹配,则 R 有效地连接数据
【发布时间】:2021-07-27 12:20:19
【问题描述】:

给定 2 个数据框:

df1

col1 col2 col3
43    21   "a"
32    31   "b"
NA    12   "c"
44    NA   "d"

df2

cl4 cl5 cl6
43   1  "text"
12   0  "text2"
32   44  "text3"

如果c("col1", "col2") 中的列值与c("cl4", "cl5") 列中的值匹配,我如何将它们与left_join 合并? 附加信息:所有变量都可以有缺失值,但总是完成的 cl6 除外。

预期结果:

col1 col2 col3 cl4 cl5 cl6
43    21   "a"  43   1 "text"
32    31   "b"  32  44 "text3"
NA    12   "c"  12   0 "text2"
44    NA   "d"  32  44 "text3"

我有一些有效的代码,但我认为如果有很多连接要做(在我的真实数据框中,我有 24 个连接要做......),我认为必须有更好的解决方案。 这是我的代码:

list_vars = c('cl4', "cl5", "cl6")
list_vars_rename = c("col4", "col5", "col6")

#MERGE 1

df1_merged <- left_join(df1, df2, by=c("col1" = "cl4"), na_matches = "never") #ignore NAs

df1_merged$cl4 <- df1_merged$col1 #because cl4 disappears during the join
df1_merged[is.na(df1_merged$cl6), "cl4"] <- NA #cl4 equals NA if no match = if cl6 NA

setnames(df1_merged, old = list_vars, new = list_vars_rename, skip_absent = T) #rename cols

#MERGE 2
df1_merged <- left_join(df1_merged, df2, by=c("col1" = "cl5"), na_matches = "never")
df1_merged <- as.data.frame(df1_merged) #because was a tibble
df1_merged$cl5 <- df1_merged$col1 #because cl4 disappears during the join
df1_merged[is.na(df1_merged$cl6), "cl5"] <- NA #cl5 equals NA if no match = if cl6 NA
for (i in seq_along(list_vars_rename)){
  df1_merged[,list_vars_rename[i]] <- ifelse(is.na(df1_merged[,list_vars_rename[i]]), df1_merged[,list_vars[i]], df1_merged[,list_vars_rename[i]])
} #fill col4, col5 & col6 with the values of cl4, cl5 & cl6 we got in the join
df1_merged = df1_merged[, !(names(df1_merged) %in% list_vars)] #drop cl4 ,cl5 & cl6

#MERGE 3
df1_merged <- left_join(df1_merged, ventes, by=c("col2" = "cl4"), na_matches = "never")
df1_merged <- as.data.frame(df1_merged)
df1_merged$cl4 <- df1_merged$col2
df1_merged[is.na(df1_merged$cl6), "cl4"] <- NA
for (i in seq_along(list_vars_rename)){
  df1_merged[,list_vars_rename[i]] <- ifelse(is.na(df1_merged[,list_vars_rename[i]]), df1_merged[,list_vars[i]], df1_merged[,list_vars_rename[i]])
}
df1_merged= df1_merged[, !(names(df1_merged) %in% list_vars)]

###etc. until the last merge.

【问题讨论】:

    标签: r join left-join


    【解决方案1】:

    我还没到那里,但也许这段代码有帮助:

    library(tidyverse)
    df1 <- read_table("col1 col2 col3
    43    21   a
    32    31   b
    NA    12   c
    44    NA   d")
    
    df2 <- read_table("cl4 cl5 cl6
    43   1  text
    12   0  text2
    32   44  text3")
    
    cols_1 <- c("col1", "col2")
    cols_2 <- c("cl4", "cl5")
    
    df1 %>% 
      pivot_longer(cols = all_of(cols_1)) %>% 
      left_join(df2 %>% pivot_longer(cols = all_of(cols_2)), by = "value", suffix = c(".df1", ".df2")) %>% 
      filter(!is.na(name.df1) & !is.na(name.df2))
    #> # A tibble: 4 x 5
    #>   col3  name.df1 value cl6   name.df2
    #>   <chr> <chr>    <dbl> <chr> <chr>   
    #> 1 a     col1        43 text  cl4     
    #> 2 b     col1        32 text3 cl4     
    #> 3 c     col2        12 text2 cl4     
    #> 4 d     col1        44 text3 cl5
    

    reprex package (v2.0.0) 于 2021 年 7 月 27 日创建

    输出包含包含重要信息的列(col3cl6),它告诉您匹配的列(name.df1name.df2),以及匹配值是什么(value) .但我不知道如何添加其他信息以匹配您想要的输出。我也没有处理NAs。

    【讨论】:

      猜你喜欢
      • 2016-10-18
      • 1970-01-01
      • 2020-12-18
      • 2018-11-12
      • 2022-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      相关资源
      最近更新 更多