【问题标题】:How to pop out non-matching column names in a series of csv files?如何在一系列csv文件中弹出不匹配的列名?
【发布时间】:2020-01-08 00:10:00
【问题描述】:

我正在读取多个 csv 文件(20 个文件)并最终创建一个数据框。虽然我用眼睛手动检查,但列名是相同的。但是,由于某种原因,我收到以下错误。

match.names(clabs, names(xi)) 中的错误: 名字与以前的名字不匹配

这是我写的代码

fnames <- list.files("C:/Users/code",pattern='^La') # getting all the files from directory. Update it as required
csv <- lapply(fnames,read.csv)  # reading all the files
source_DF <- do.call(rbind, lapply(csv, '[', 1:8)) # This is the line where it throws error

请注意,我使用1:8 是因为有时 R 会读取奇数列。例如,我所有的 csv 文件只有 8 列,但当它读取时,有时它有 12 列,有些甚至有 50 列。所以,为了避免这种情况,我得到了1:8。也欢迎任何其他阅读前 8 列的方法

如何找出哪个 csv 文件存在此命名问题以及导致此问题的列是什么?

任何解决此错误的帮助都会很有帮助

【问题讨论】:

  • 供将来参考:包含可重现的示例以及预期的输出会很有帮助,以便其他人能够准确地回答您的问题。
  • 当然。但在这种情况下,除了我的代码,我不知道如何分享示例
  • 问题的核心是你有一个数据框列表,其中一些有不同的名称:简单地创建一些这样的假数据。好读:stackoverflow.com/a/5963610/4550695
  • 谢谢。会遵循的

标签: r dataframe lapply sapply rbind


【解决方案1】:

我会在这里使用一个循环,并检查每组名称与之前的名称:

dfs <- list(
  data.frame(foo = 1, bar = 2),
  data.frame(foo = 2, bar = 2),
  data.frame(foo = 3, baz = 2),
  data.frame(foo = 4, bar = 2)
)

for (i in seq_len(length(dfs) - 1)) {
  different <- names(dfs[[i]]) != names(dfs[[i + 1]])
  if (any(different)) {
    message("Names of column(s) ", paste(which(different), collapse = ", "),
            " in data frame ", i + 1, " differ from the previous ones.")
  }
}
#> Names of column(s) 2 in data frame 3 differ from the previous ones.
#> Names of column(s) 2 in data frame 4 differ from the previous ones.

或者,如果您只是想存储不匹配:

mismatches <- list(integer())
for (i in seq_len(length(dfs) - 1)) {
  different <- names(dfs[[i]]) != names(dfs[[i + 1]])
  mismatches[[i + 1]] <- which(different)
}

str(mismatches)
#> List of 4
#>  $ : int(0) 
#>  $ : int(0) 
#>  $ : int 2
#>  $ : int 2

reprex package (v0.3.0.9000) 于 2019-09-05 创建

【讨论】:

  • 但是没有其他方法可以做到这一点吗?我有超过 20 个数据框,每个 df 有超过 30 列。虽然示例是 8
  • 我看不出数据框或列的数量与此有什么关系?解决方案是相同的——这明确回答了您的问题,即哪些文件具有不同的名称,哪些列是不同的。如果您想计算该信息,您只需为每次迭代保存它。
  • 我的答案和@ronakshah 的不同之处在于“事实来源”:我的将以前的名字作为“正确”的名字,这与导致rbind() 错误的原因相匹配,而他们的名字则是出现在所有数据帧中的一组名称:这意味着如果任何地方有任何不同的名称,您将得到 all 数据帧的“不匹配”。
【解决方案2】:

检查它的一种方法是将每个数据帧的前 8 列子集化,获取所有数据帧中存在的通用名称,然后使用 setdiff 找出列名称是否不匹配

list_df <- lapply(csv, '[', 1:8)
cols <- Reduce(intersect, lapply(list_df, names))
lapply(list_df, function(x) setdiff(names(x), cols))

如果您的所有列名都相同,您应该得到character(0) 作为每个数据帧的输出。如果有任何不匹配,setdiff 将显示列的名称。

另一个要检查的提示是length(cols) 8 ?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2022-08-17
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多