【问题标题】:Binding dataframes in list after data cleaning on list对列表进行数据清理后在列表中绑定数据帧
【发布时间】:2019-07-02 15:13:45
【问题描述】:

这是对我上一个问题 (Rbinding large list of dataframes after I did some data cleaning on the list) 的跟进。我变得更聪明了,前一个问题变得一团糟。

我有 43 个 xlsx 文件,我将它们加载到 R 中的列表中:

file.list <- list.files(recursive=T,pattern='*.xlsx')

dat = lapply(file.list, function(i){
x = read_xlsx(i, sheet=1, col_names = T)

# Create column with file name  
x$file = i
# Return data
x
})

然后我添加了一些列名:

my_names <- c("ID", "UDLIGNNR","BILAGNR", "AKT", "BA",
          "IART", "HTRANS", "DTRANS", "BELOB", "REGD",
          "BOGFD", "VALORD", "UDLIGND", 
          "UÅ", "AFSTEMNGL", "NRBASIS","FIBILAG", "FILE")
dat <- lapply(dat, setNames, my_names)

然后我删除了一些列:

dat <- lapply(dat, function(x) { x["UÅ"] <- NULL; x })
dat <- lapply(dat, function(x) { x["FIBILAG"] <- NULL; x })

我真的不需要删除它们,但是当我尝试合并数据框时,我不断收到关于这些类的错误。所以我只是删除了它们。

然后我将所有列更改为字符。我对 R 有点陌生,所以我知道这段代码不是很性感,你可能已经为此创建了一个循环或一个函数。但这就是我所做的:

dat <- lapply(dat, function(x) { x["ID"] <- as.character(x["ID"]); x })

[我对所有列都做了同样的处理]

然后我去绑定数据。

df <- rbindlist(dat)

编辑:

我发现问题不是我的绑定方法(感谢您对此的投入)。我已经删除了关于绑定方法的部分。

问题在于我如何更改列表中数据框中列的 coltypes。

我也试过了:

    dat <- lapply(dat, function(x) { x[,"ID"] <- as.character(x[,"ID"]); x })

我在“ID”之前添加了一个逗号。这没有帮助。感觉需要用unlist,但是这里不知道怎么用?

【问题讨论】:

  • 你不需要do.call(rbindlist,应该是rbindlist(dat)。关于代码的另一部分dat[] &lt;- lapply(dat, function(x) setDT(dat)[, (my_names) := lapply(.SD, as.character), .SDcols = my_names])
  • 当我使用 dat[] &lt;- lapply(dat, function(x) setDT(dat)[, (my_names) := lapply(.SD, as.character), .SDcols = my_names]) 时,我的数据框列表被转换为具有 18 个观察值(每个数据框有 18 列)和 43 列(列表中有 43 个数据框)的数据框.
  • 对不起,代码有错别字,我的意思是setDT(x)
  • 好的,现在它说它是一个列表,其中包含一个数据框为 18 x 43 的列表。使用您建议的 rbindlist 时,我得到 df 有 18 个 obs 和 43 列。好像还有什么问题?
  • 使用 rbindlist 提供与 do.call(rbind,dat) 相同的输出

标签: r merge rbind rbindlist


【解决方案1】:

如果你有 dat 的数据框列表,我会推荐

df <- dplyr::bind_rows(dat)

将它们行绑定到一个大数据框。

或者,您应该使用 purrr 映射系列并直接返回一个行绑定的 data.frame?

df <- purrr::map_dfr(file.list, function(x) readxl::read_xslx(x))

【讨论】:

  • purr 解决方案不起作用,因为我有一列是某些 xlsx 文件中的数字和其他文件中的字符,因此在合并之前我需要将其转换为字符。
  • 另外,readxl::read_xlsx 允许您在通过 col_types 参数解析列时指定列类型
  • 我刚刚尝试使用 read_xlsx - 所以我再次删除了我的评论 :) 我将尝试设置 colnames,删除列,然后与 bind_rows 合并,看看它是否做了任何我跳过数据清理的事情。手指交叉。数据很大,所以每次尝试都需要一段时间。
  • 好的,所以现在我收到错误Error in bind_rows_(x, .id) : Column AKT can't be converted from numeric to character,我有点需要该列,所以不能只删除它...我尝试了整列转换(请参阅上面的代码),我想也许这就是错误所在......你认为我应该在转换为角色时使用 unlist 吗?
  • 请查看我对问题的编辑 - 问题不是绑定,而是 coltypes。
【解决方案2】:

我找到了解决办法!!

感谢您的帮助!

显然问题不在于嵌套列表中数据框的绑定。问题是我以错误的方式更改列类型。

这是我的代码 - 它有效!而且它比另一个更快!

file.list <- list.files(recursive=T,pattern='*.xlsx')

dat = lapply(file.list, function(i){
x = read_xlsx(i, sheet=1, col_names = T)

# Create column with file name  
x$file = i
# Return data
x
})

# Setting column names
my_names <- c("ID", "UDLIGNNR","BILAGNR", "AKT", "BA",
          "IART", "HTRANS", "DTRANS", "BELOB", "REGD",
          "BOGFD", "VALORD", "UDLIGND", 
          "UÅ", "AFSTEMNGL", "NRBASIS","FIBILAG", "FILE")

dat <- lapply(dat, setNames, my_names)

# Removing problematic columns
dat <- lapply(dat, function(x) { x["UÅ"] <- NULL; x })
dat <- lapply(dat, function(x) { x["FIBILAG"] <- NULL; x })


dat2 <- lapply(dat, function(df) setDT(df)[, (1:16) := lapply(.SD, as.character), .SDcols = 1:16])

# Merging
df <- rbindlist(dat2)

哦,有几个人告诉我改用 bind_rows(@atomman 和 @Probel)

我想感谢我偷了第一部分的人,但我不记得了......

【讨论】:

    猜你喜欢
    • 2021-07-25
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多