【问题标题】:Make rbindlist skip, ignore or change class attribute of the column使 rbindlist 跳过、忽略或更改列的类属性
【发布时间】:2019-09-06 11:04:24
【问题描述】:

我想合并一大组数据框(大约 30 个),每个数据框有大约 200 个变量。这些数据集非常相似,但并不完全相同。

请在下面找到两个示例数据框:

library(data.table)
library(haven)
df1 <- fread(
    "A   B   C  iso   year   
     0   B   1  NLD   2009   
     1   A   2  NLD   2009   
     0   Y   3  AUS   2011   
     1   Q   4  AUS   2011   
     0   NA  7  NLD   2008   
     1   0   1  NLD   2008   
     0   1   3  AUS   2012",
  header = TRUE
)
df2 <- fread(
    "A   B   D  E  iso   year   
     0   1   1  NA ECU   2009   
     1   0   2  0  ECU   2009   
     0   0   3  0  BRA   2011   
     1   0   4  0  BRA   2011   
     0   1   7  NA ECU   2008   
     1   0   1  0  ECU   2008   
     0   0   3  2  BRA   2012   
     1   0   4  NA BRA   2012",
  header = TRUE
)

重现错误:

class(df2$B) <- "anything"

当我执行以下操作时

df_merged <- rbindlist(list(df1, df2), fill=TRUE, use.names=TRUE)

数据集给出错误:

Error in rbindlist(list(df1, df2), fill = TRUE, use.names = TRUE) : 
  Class attribute on column 2 of item 2 does not match with column 2 of item 1.

我能做什么:

  1. 使rbindlist跳过不匹配的列并添加一些后缀。
  2. 将其中一列的类更改为另一列。

选项 1 的期望结果:

df_merged <- fread(
    "A   B  B.x  C  D   E   iso   year   
     0   A   NA  1  NA  NA  NLD   2009   
     1   Y   NA  2  NA  NA  NLD   2009   
     0   Q   NA  3  NA  NA  AUS   2011   
     1   NA  NA  4  NA  NA  AUS   2011   
     0   0   NA  7  NA  NA  NLD   2008   
     1   1   NA  1  NA  NA  NLD   2008   
     0   1   NA  3  NA  NA  AUS   2012   
     0   NA  1   NA  1  NA  ECU   2009   
     1   NA  0   NA  2  0   ECU   2009   
     0   NA  0   NA  3  0   BRA   2011   
     1   NA  0   NA  4  0   BRA   2011   
     0   NA  1   NA  7  NA  ECU   2008   
     1   NA  0   NA  1  0   ECU   2008   
     0   NA  0   NA  3  2   BRA   2012   
     1   NA  0   NA  4  NA  BRA   2012",
   header = TRUE
)

选项 2 的预期结果:

df_merged <- fread(
    "A   B   C  D   E   iso   year   
     0   3   1  NA  NA  NLD   2009   
     1   4   2  NA  NA  NLD   2009   
     0   5   3  NA  NA  AUS   2011   
     1   5   4  NA  NA  AUS   2011   
     0   0   7  NA  NA  NLD   2008   
     1   1   1  NA  NA  NLD   2008   
     0   1   3  NA  NA  AUS   2012   
     0   1   NA  1  NA  ECU   2009   
     1   0   NA  2  0   ECU   2009   
     0   0   NA  3  0   BRA   2011   
     1   0   NA  4  0   BRA   2011   
     0   1   NA  7  NA  ECU   2008   
     1   0   NA  1  0   ECU   2008   
     0   0   NA  3  2   BRA   2012   
     1   0   NA  4  NA  BRA   2012",",
   header = TRUE
)

【问题讨论】:

  • 它没有给我任何错误,并给出了您想要的结果选项 2。
  • 你看到这部分了吗:class(df2$B) &lt;- "haven_labelled"
  • 是的,仍然。没有错误。不知道两端可能是什么问题。
  • 这真的很奇怪。在回复您之前,我从帖子中复制了它(以重新测试它)..
  • 我确实遇到了同样的问题@Tom!如果有人提供解决方案 2,将非常高兴。

标签: r class merge rbind rbindlist


【解决方案1】:

我想出了这个绕过问题的不优雅解决方案。基本上,我正在做的是将列表第一项的列的属性分配给与列表中所有其他项具有相同名称的列。请记住,此解决方案存在问题,并且根据项目的不同,这可能是一种非常错误的做法,因为它有可能弄乱您的数据。但是,如果您需要使用 rbindlist 来组合您的数据帧,那么这就是诀窍


dfs <- list(df1, df2)
varnames <- names(dfs[[1]]) # variable names
vattr <- purrr::map_chr(varnames, ~class(dfs[[1]][[.x]])) # variable attributes

for (i in seq_along(dfs)) {
  # assign the same attributes of list 1 to the rest of the lists
  for (j in seq_along(varnames)) {
    if (varnames[[j]]  %in% names(dfs[[i]])) {
      class(dfs[[i]][[varnames[[j]]]]) <- vattr[[j]]
    } 
  }
}


df_merged <- data.table::rbindlist(dfs, fill=TRUE, use.names=TRUE)

最好的,

【讨论】:

  • 非常感谢您发布这个!
  • 我一直在使用您的解决方案,但现在出现错误:Warning messages: 1: In class(All[[i]][[varnames[[j]]]]) &lt;- vattr[[j]] : NAs introduced by coercion(其中四个)。我无法真正弄清楚它们发生的地点或原因。但我想知道,他们只是让类 NA 吗?还是他们将实际变量设为 NA?
【解决方案2】:

@R.Andres Castaneda 的回答更不优雅的解决方案是:

当使用fread 设置colClasses = "character" 将所有内容强制转换为角色时,请执行rbindlist,然后选择您喜欢的方法,然后将所有内容强制转换为合理的内容。

这并不优雅,但在读取不一致的数据时,我经常发现这是最简单的方法。

【讨论】:

    【解决方案3】:

    尝试ldply(list, data.frame) 作为解决方法。为我工作,rbindlist() 不喜欢日期列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      相关资源
      最近更新 更多