【问题标题】:How to find rows with same values in two columns?如何在两列中查找具有相同值的行?
【发布时间】:2021-08-02 09:31:15
【问题描述】:

这有点难以解释,但我试图比较来自两个不同数据帧的“cpf”列。我想确定(df1)和(df2)的两个“cpf”列中的值何时相等(这些值可以在不同的行中)。之后,我想更新 NA 值,如果这些值可从其他数据框中获得

df1 
    cpf x  y
1   21  NA NA
2   32  NA NA
3   43  NA NA
4   54  NA NA
5   65  NA NA

df2 
    cpf x  y
1   54  5  10
2   0   NA NA
3   65  3   2
4   0   NA NA
5   0  NA NA

我想要以下结果

df3 
    cpf x  y
1   21  NA NA
2   32  NA NA
3   43  NA NA
4   54  5  10
5   65  3   2

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我们可以在 'cpf' 上执行 join 并使用 fcoalecse

    library(data.table)
    setDT(df1)[df2, c('x', 'y') := .(fcoalesce(x, i.x), 
            fcoalesce(y, i.y)), on = .(cpf)]
    

    -输出

    df1
    #   cpf  x  y
    #1:  21 NA NA
    #2:  32 NA NA
    #3:  43 NA NA
    #4:  54  5 10
    #5:  65  3  2
    

    或者在left_join之后使用dplyr中的coalecse

    library(dplyr)
    left_join(df1, df2, by = 'cpf') %>%
         transmute(cpf, x = coalesce(x.x, x.y), y = coalesce(y.x, y.y))
    #  cpf  x  y
    #1  21 NA NA
    #2  32 NA NA
    #3  43 NA NA
    #4  54  5 10
    #5  65  3  2
    

    base R,可以使用match

    i1 <- match(df1$cpf, df2$cpf, nomatch = 0)
    i2 <- match(df2$cpf, df1$cpf, nomatch = 0)
    df1[i2, -1] <- df2[i1, -1]
    

    数据

    df1 <- structure(list(cpf = c(21L, 32L, 43L, 54L, 65L), x = c(NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_), y = c(NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_)), row.names = c("1", 
    "2", "3", "4", "5"), class = "data.frame")
    
    df2 <- structure(list(cpf = c(54L, 0L, 65L, 0L, 0L), x = c(5L, NA, 3L, 
    NA, NA), y = c(10L, NA, 2L, NA, NA)), class = "data.frame", row.names = c("1", 
    "2", "3", "4", "5"))
    

    【讨论】:

    • 谢谢!!是否可以运行此代码“setDT(df1)[df2, c('x', 'y') := .(fcoalesce(x, ix), fcoalesce(y, iy)), on = .(cpf) ]”,名称为“gad”、“phq”...?只有当我把名字改成“x”、“y”时我才能做到……
    • @MarcosO.C.Alves 只需更改它c('gad', 'phq') := .(fcoalesce(gad, i.gad), fcoalesce(phq, i.phq))
    【解决方案2】:
    df1 %>% 
      left_join(df2, by = "cpf") %>% 
      select(cpf, x = x.y, y = y.y)
    

    输出:

      cpf  x  y
    1  21 NA NA
    2  32 NA NA
    3  43 NA NA
    4  54  5 10
    5  65  3  2
    

    【讨论】:

      【解决方案3】:

      另一个使用merge的基本R选项

      merge(df1,
        df2,
        by = "cpf",
        all.x = TRUE,
        suffixes = c(".x", "")
      )[names(df1)]
      

      给予

        cpf  x  y
      1  21 NA NA
      2  32 NA NA
      3  43 NA NA
      4  54  5 10
      5  65  3  2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-07
        • 2012-06-18
        • 1970-01-01
        • 2016-01-27
        • 2010-12-19
        • 2016-06-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多