比较两个数据框架之间的列类型

3

这可能是一个不好的问题,因为我没有提供可重现的示例。我的主要目标是识别在两个具有相同列名的数据帧之间类型不同的列。

例如:

df1

 Id      Col1      Col2     Col3
 Numeric Factor    Integer  Date

df2

 Id      Col1      Col2     Col3
 Numeric Numeric    Integer  Date

这里,数据框 df1 和 df2 具有相同的列名,但 Col1 的类型不同,我希望能够识别出这些列。期望输出结果。

Col1  Factor    Numeric

有关实现此目标的任何建议或技巧吗?谢谢。
5个回答

6
尝试使用janitor包中的compare_df_cols():
library(janitor)
mtcars2 <- mtcars
mtcars2$cyl <- as.character(mtcars2$cyl)
compare_df_cols(mtcars, mtcars2, return = "mismatch")

#>   column_name  mtcars   mtcars2
#> 1         cyl numeric character

个人推广提醒,我是这个包的作者 - 发布该函数是因为它正好可以解决这个问题。


3

试试这个:

compareColumns <- function(df1, df2) {
  commonNames <- names(df1)[names(df1) %in% names(df2)]
  data.frame(Column = commonNames,
             df1 = sapply(df1[,commonNames], class),
             df2 = sapply(df2[,commonNames], class)) }

1
谢谢Alex提供的出色解决方案,我添加了一些类似下面的代码:df3 <- compareColumns(df1,df2) df3$Diff <- ifelse(df3$df1== df3$df2, "Same", "Different") df3[df3$Diff =="Different",] - Science11

3

为了更加简洁的方法,你可以使用一个带有sapply()的列表。效率不应该是一个问题,因为我们所做的只是获取类。在这里,我将数据框名称添加到列表中,以创建更清晰的输出。

m <- sapply(list(df1 = df1, df2 = df2), sapply, class)
m[m[, "df1"] != m[, "df2"], , drop = FALSE]
#      df1      df2        
# Col1 "factor" "character"

其中df1df2是来自@ycw答案的数据。


2
如果两个数据框拥有相同的列名,那么下面的代码将会提取出数据类型不同的列。
library(dplyr)
m1 = mtcars
m2 = mtcars %>% mutate(cyl = factor(cyl), vs = factor(cyl))
out = cbind(sapply(m1, class), sapply(m2, class))
out[apply(out, 1, function(x) !identical(x[1], x[2])), ]

0
我们可以使用 sapplyclass 循环遍历 df1df2 中的所有列。之后,我们可以比较结果。
# Create example data frames
df1 <- data.frame(ID = 1:3,
                  Col1 = as.character(2:4),
                  Col2 = 2:4,
                  Col3 = as.Date(paste0("2017-01-0", 2:4)))

df2 <- data.frame(ID = 1:3,
                  Col1 = as.character(2:4),
                  Col2 = 2:4,
                  Col3 = as.Date(paste0("2017-01-0", 2:4)),
                  stringsAsFactors = FALSE)

# Use sapply and class to find out all the class
class1 <- sapply(df1, class)
class2 <- sapply(df2, class)

# Combine the results, then filter for rows that are different
result <- data.frame(class1, class2, stringsAsFactors = FALSE)
result[!(result$class1 == result$class2), ]
     class1    class2
Col1 factor character

@Sagar 谢谢!但我刚意识到我犯了一个错误。%in%不适用于过滤行,因为比较不限于相同的位置。例如,c("factor", "character", "numeric") %in% c("factor", "numeric", "Date") 的结果是 TRUE FALSE TRUE,但我们需要的是 TRUE, FALSE, FALSE。我刚刚用==替换了%in%,这使得比较一对一。 - www
不错。之前我运行过,也没问题,但提出来还是很好的。然而现在我无法给任何东西点赞,一直提示错误。 - Sagar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接