尝试逐行比较 R 中具有多列的两个数据帧并标记不正确的行

Trying to compare two dataframes with many columns in R row by row and label the incorrect rows

我基本上想做的是将一个包含有限行数和列数的数据集(其中每一行都被验证为正确)与另一个会随时间变化的数据集进行比较,我需要确定第二个数据集中的哪些行与第一个不匹配。这可以与我有答案键(数据框 1)和一个包含数百万行的数据框进行比较,我需要将其与答案键进行比较以确定哪些行匹配。

我已经阅读了很多解决方案,但还没有找到一个简洁的解决方案 - 有什么建议吗?

添加示例数据集以支持 - 数据集 1

library(tibble)

df1 <- tribble(
  ~bc, ~var1, ~var2, ~var3,
  "A", 324, 468, 462,
  "B", 223, 362, 328,
  "C", 187, 200, 229,
  "D", 286, 455, 423)

数据集 2

df2 <- tribble(
  ~bc, ~var1, ~var2, ~var3,
  "A", 324, 468, 462,
  "B", 223, 362, 328,
  "C", 187, 200, 229,
  "D", 286, 455, 423,
  "A", 324, 468, 462,
  "B", 223, 362, 421,
  "D", 286, 455, 423)

我想做的是通过与数据集 1 匹配的变量 bc 检查数据集 2。例如,数据集 2 中的第二个 D bc 不匹配与数据集 1 不匹配

没有看到任何数据,很难回答你。

使用 which 函数可以告诉您哪些行符合某些条件。 下面是一个如何使用 which 的例子。 您可以将其更改为 which(df2$answers %in% df1$answer_key) 或类似内容

# Load the data
data(iris)

# Take a look
head(iris)
which_example <- c(5.4, 4.6)

# The way I think of which is to ask R "which rows in iris$Sepal.Length are 5.4?"
which(iris$Sepal.Length %in% 5.4)
which(iris$Sepal.Length %in% which_example)

# Once you have the rows, you can display only those specific rows and all or some columns
# The format is df[row,column] 
# Which gives the rows. You can leave column blank to get all or enter specific ones
iris[which(iris$Sepal.Length %in% 5.4),]
iris[which(iris$Sepal.Length %in% 5.4),c(2,4)]

您或许可以使用 dplyr 包中的 setdiff 函数。它显示不同的行。

library(dplyr)

# Create example data frame
mtcars_edit <- mtcars
# Change the 1, 3, and 5 of wt column to 1
mtcars_edit$wt[c(1, 3, 5)] <- 1

# Apply the setdiff function
setdiff(mtcars, mtcars_edit)
#                    mpg cyl disp  hp drat   wt  qsec vs am gear carb
# Mazda RX4         21.0   6  160 110 3.90 2.62 16.46  0  1    4    4
# Datsun 710        22.8   4  108  93 3.85 2.32 18.61  1  1    4    1
# Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.02  0  0    3    2

正如 Ronak Shah 在评论中所说,anti-join 可能是这里的解决方案,如果我们理解正确的话。这里有更简单的数据集,更容易复制。为了更容易发现不匹配,它们在示例数据中为负数。

此外,为了识别哪些列不匹配,您可以添加一个 id 变量。

library(tidyverse)

df1 <- tribble(
  ~bc, ~var1, ~var2, ~var3, 
  "A",     1,     2,     3,
  "B",     4,     5,     6,
)

df2 <- tribble(
  ~bc, ~var1, ~var2, ~var3, 
  "A",     1,     2,     3,
  "B",     4,     5,     6,
  "A",     1,     2,     3,
  "B",     4,     5,    -1,
  "A",    -1,     2,     3,
  "B",     4,     5,     6,
)

# add id to identify which rows are not matching
df2 <- df2 %>% mutate(id = row_number())


(df_unmatch <- dplyr::anti_join(df2, df1, by = c("var1", "var2", "var3")))
#> # A tibble: 2 x 5
#>   bc     var1  var2  var3    id
#>   <chr> <dbl> <dbl> <dbl> <int>
#> 1 B         4     5    -1     4
#> 2 A        -1     2     3     5

# list of non-match are the ids of df_unmatch
df_unmatch$id 
#> [1] 4 5

# with that you can create a new variable in df two, for instance
df2 %>% mutate(correct_match = if_else( !(id %in% df_unmatch$id), TRUE, FALSE))
#> # A tibble: 6 x 6
#>   bc     var1  var2  var3    id correct_match
#>   <chr> <dbl> <dbl> <dbl> <int> <lgl>        
#> 1 A         1     2     3     1 TRUE         
#> 2 B         4     5     6     2 TRUE         
#> 3 A         1     2     3     3 TRUE         
#> 4 B         4     5    -1     4 FALSE        
#> 5 A        -1     2     3     5 FALSE        
#> 6 B         4     5     6     6 TRUE

reprex package (v2.0.0)

于 2021 年 6 月 12 日创建