【问题标题】:Compare each row in two dataframes in R比较R中两个数据帧中的每一行
【发布时间】:2021-09-16 18:43:10
【问题描述】:

我有 2 个数据框,其中包含帐号和金额以及其他一些不相关的列。如果匹配与否,我想将输出与 Y 或 N 进行比较。

我需要将数据框 A 中第 1 行中的帐号与数据框 B 中第 1 行中的帐号进行比较,如果它们匹配,则将 Y 放在列中,如果不匹配,则将 N 放在列中。我已经设法获取代码来检查整个数据框中是否存在匹配项,但我需要单独检查每一行。

例如 df1
|account.num|x1|x2|x3|
|100|a|b|c|
|101|a|b|c|
|102|a|b|c|
|103|a|b|c|

df2
|account.num|x1|x2|x3|
|100|a|b|c|
|102|a|b|c|
|101|a|b|c|
|103|a|b|c|

输出
|account.num|x1|x2|x3|匹配|
|100|a|b|c|Y|
|101|a|b|c|N|
|102|a|b|c|N|
|103|a|b|c|Y|

因此,第 1 行匹配,因为它们具有相同的帐号,但第 2 行不匹配,因为它们不同。但是,数据框中的其他数据与该列无关。我可以在不合并数据框的情况下执行此操作吗? (我确实有桌子,但它们不起作用。我不知道为什么。如果这很难理解,请见谅)。

【问题讨论】:

标签: r


【解决方案1】:

您可以使用== 比较account.num 是否相等,并使用此布尔向量对c("N", "Y") 进行子集化

df1$match <- c("N", "Y")[1 + (df1[[1]] == df2[[1]])]

df1
#  account.num x1 x2 x3 match
#1         100  a  b  c     Y
#2         101  a  b  c     N
#3         102  a  b  c     N
#4         103  a  b  c     Y

数据:

df1 <- data.frame(account.num=100:103, x1="a", x2="b", x3="c")
df2 <- data.frame(account.num=c(100,102,101,103), x1="a", x2="b", x3="c")

【讨论】:

    【解决方案2】:

    如果你想要一个基本的 R 解决方案,这里有一个速写。假设船数据帧的长度(行数)相同,它应该适用于您的数据。

    # example dataframes
    a <- data.frame(A=c(1,2,3), B=c("one","two","three"))
    b <- data.frame(A=c(3,2,1), B=c("three","two","one"))
    
    
    res <- c() #initialise empty result vector
    
    for (rownum in c(1:nrow(a))) {
      # iterate over all numbers of rows
      res[rownum]  <- all(a[rownum,]==b[rownum,])
    }
    
    res # result vector
    # [1] FALSE  TRUE FALSE
    
    # you can put it in frame a like this. example colname is "equalB"
    a$equalB <- res
    

    【讨论】:

      【解决方案3】:

      如果您想要tidyverse 解决方案,可以使用left_join

      这里的原则是尝试将df2的数据与df1的数据进行匹配。如果匹配,它会将TRUE 添加到match 列。然后,代码将NA 值替换为FALSE

      我还添加了代码以从示例中创建数据框。

      library(tidyverse)
      
      df1 <- 
        tribble(~account_num, ~x1, ~x2, ~x3,
                         100, "a", "b", "c",
                         101, "a", "b", "c",
                         102, "a", "b", "c",
                         103, "a", "b", "c") %>%
        rowid_to_column() # because position in the df is an important information, 
                          # I need to hardcode it in the df
      
      df2 <- 
        tribble(~account_num, ~x1, ~x2, ~x3,
                         100, "a", "b", "c",
                         102, "a", "b", "c",
                         101, "a", "b", "c",
                         103, "a", "b", "c") %>%
        rowid_to_column()
      
      # take a
      df1 %>% 
        # try to match df1 with version of df2 with a new column where `match` = TRUE
        # according to `rowid`, `account_num`, `x1`, `x2`, and `x3`
        left_join(df2 %>% 
                    tibble::add_column(match = TRUE),
                  by = c("rowid", "account_num", "x1", "x2", "x3")
        ) %>% 
        # replace the NA in `match` with FALSE in the df
        replace_na(list(match = FALSE))
      

      【讨论】:

        猜你喜欢
        • 2017-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多