【问题标题】:How to compare if two data frames have identical column names and classes?如何比较两个数据框是否具有相同的列名和类?
【发布时间】:2018-09-03 04:28:28
【问题描述】:

我想比较两个数据框并检查它们是否具有相同的列集,R 中是否有任何内置函数或任何库?这些数据框的值可能不同,但两个数据框将具有相同的类型和命名列。

我尝试在 mtcars 和副本数据帧上运行 identicalall_equal

duplicate <- mtcars

identical(mtcars, duplicate)    
[1] TRUE

all_equal(mtcars, duplicate)
[1] TRUE

然后我更新了 data.frame 副本的 mpg 列,使其具有与 mtcars 不同的值:

duplicate$mpg <- as.numeric(scale(duplicate$mpg))

再次运行相同的命令:

identical(mtcars, duplicate)

[1] FALSE

all_equal(mtcars, duplicate)
[1] "Rows in x but not y: 23, 1, 6, 14, 10, 12, 13, 17, 28, 32, 7[...]. Rows in y but not x: 12, 25, 1, 20, 30, 5, 14, 7, 11, 29, 21[...]. "

现在它们显示为不相同的数据框。

我想在第二种情况下比较和检查值不同但列名及其类型相同的情况。基本上,如果两者具有相同的架构。

【问题讨论】:

  • 您可以通过identical(names(dat1), names(dat2))identical(sapply(dat1, class), sapply(dat2, class))查看
  • 根据您的数据,结合这两个逻辑条件应该可以identical(names(mtcars), names(duplicate)) &amp; identical(sapply(mtcars, class), sapply(duplicate, class))# [1] TRUE。您也可以查看library(diffObj);diffObj(mtcars, duplicate)
  • all.equal(mtcars, duplicate, tolerance = Inf)
  • @rawr:我对这个问题的理解(很可能不正确)是内部值和行数都不是问题。无论如何,提问者现在有几个选择来满足他的目的。

标签: r dataframe


【解决方案1】:

我认为这个问题的答案是:数据帧是否有 R“相同模式”功能是“可能没有”。 R 数据框并没有真正的数据库结构。如果您想测试名称和类的相等性,@akrun 为您提供了一个由两部分组成的解决方案。这将是另一种基本上清空数据框但保留其列名和类的方法:

identical(duplicate[NA,][1,], mtcars[NA,][1,])
[1] TRUE

这不仅检查名称,还检查整个对象的类和底层列的类,可以使用以下方法进行测试:

 my.schema <-  mtcars[NA,][1,] 
 my_schema[['mpg']] <- NA_integer_

identical(duplicate[NA,][1,], my.schema)
[1] FALSE

仅仅将类从 double 更改为 integer 就导致 identical 报告非身份。 identity 函数可能相当挑剔,人们已经问了很多关于为什么报告 FALSE 的问题。即使存在属性差异(在对象的打印输出中通常不“可见”)也会被报告为“不同”。

为数据框创建“模式”的另一种方法(可能更优雅和直观)是使用 0 索引行:

mtcars[0,]

sapply( mtcars[0,] , class)
      mpg       cyl      disp        hp      drat        wt      qsec        vs 
"numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 
       am      gear      carb 
"numeric" "numeric" "numeric" 

【讨论】:

  • 是的。我认为这是新的 R 用户经常误解的东西:“R 数据框并没有真正的数据库结构”
【解决方案2】:

compare_df_cols_same() janitor em>包检查数据是否具有相同的列名称,并且这些列的类匹配:

library(janitor)
duplicate <- mtcars
duplicate$mpg <- as.numeric(scale(duplicate$mpg))
compare_df_cols_same(mtcars, duplicate)
#> [1] TRUE

相关的compare_df_cols(mtcars, duplicate) 允许进行更详细的比较,以查看哪些列匹配或不匹配。

完全披露:我维护这个包并提供这个答案,因为你问是否有一个库完全包含这个函数 - 现在有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多