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



我主要想做的是将一个由有限行和列组成的数据集(其中每一行都被验证为正确(与另一个将随时间变化的数据集进行比较,我需要确定第二个数据集中的哪些行与第一个数据集不匹配。这可以与我有答案键(数据帧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的示例。您可以将其更改为说出哪个(df2$在%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

创建于2021-06-12由reprex包(v2.0.0(

最新更新