附加具有不同列数量和拼写的 csv
Posted
技术标签:
【中文标题】附加具有不同列数量和拼写的 csv【英文标题】:Appending csvs with different column quantities and spellings 【发布时间】:2021-02-24 22:09:48 【问题描述】:没什么太复杂的,在大量 csvs 上使用 rbindlist 会很有用,其中列名会随着时间的推移而发生一些变化(拼写变化很小),列顺序保持不变,并且在某些时候,另外两个列被添加到 csvs(我并不真正需要)。
library(data.table)
csv1 <- data.table("apple" = 1:3, "orange" = 2:4, "dragonfruit" = 13:15)
csv2 <- data.table("appole" = 7:9, "orangina" = 6:8, "dragonificfruit" = 2:4, "pear" = 1:3)
l <- list(csv1, csv2)
当我跑步时
csv_append <- rbindlist(l, fill=TRUE) #which also forces use.names=TRUE
它给了我一个包含 7 列的 data.table
apple orange dragonfruit appole orangina dragonificfruit pear
1: 1 2 13 NA NA NA NA
2: 2 3 14 NA NA NA NA
3: 3 4 15 NA NA NA NA
4: NA NA NA 7 6 2 1
5: NA NA NA 8 7 3 2
6: NA NA NA 9 8 4 3
与我想要的相反,即:
V1 V2 V3 V4
1: 1 2 13 NA
2: 2 3 14 NA
3: 3 4 15 NA
4: 7 6 2 1
5: 8 7 3 2
6: 9 8 4 3
我可以使用它,即使稍后我必须通过额外的步骤将列重命名为标准变量名。
如果我改为尝试默认的 fill=FALSE 和 use.names=FALSE,则会引发错误:
Error in rbindlist(l) :
Item 2 has 4 columns, inconsistent with item 1 which has 3 columns. To fill missing columns use fill=TRUE.
是否有一种简单的方法来管理此问题,或者通过某种方式强制 fill=TRUE 和 use.names=FALSE,或者通过指定要追加的列向量来省略 csv 中包含它们的其他列?
【问题讨论】:
【参考方案1】:如果我们只需要前 3 列,则删除其余列并照常绑定:
rbindlist(lapply(l, function(i) i[, 1:3]))
# apple orange dragonfruit
# 1: 1 2 13
# 2: 2 3 14
# 3: 3 4 15
# 4: 7 6 2
# 5: 8 7 3
# 6: 9 8 4
另一个选项,来自 cmets:我们可以直接读取文件,并使用 fread 设置只保留前 3 列,然后绑定:
rbindlist(lapply(filenames, fread, select = c(1:3)))
【讨论】:
这是否适用于使用 fread 读取实际的 csv 文件?我对上面的问题进行了缩写,但我正在运行的完整嵌套 rbindlist 将是:rbindlist(lapply(filenames,fread)),其中 filenames 是我所有 csv 文件的列表。那么这会变成 rbindlist(lapply(filenames,fread(i) i[, 1:3])) 吗?我现在就试试这个来测试自己。 编辑:我自己对此进行了测试,并给出了 lapply,有效的代码是:rbindlist(lapply(filenames,fread, select = c(1:3)))。有趣的是,它并没有像我预期的那样返回列名作为 V1 等,而是返回在最后导入的 csv 中拼写的列名。默认 use.names 是 FALSE,所以我不确定它为什么这样做,但现在我也不必替换列名。 @fuzzydata 已编辑,直接从文件中读取,绑定前选择3列。【参考方案2】:这是一个使用来自stringdist
的phonetic
进行名称匹配的选项。从data.table
('nmlist')的list
中提取列名,unlist
,使用phonetic
分组,得到第一个元素,relist
它与'nmlist'相同的list
结构,使用Map
改变data.table的list
的列名,然后应用rbindlist
library(stringdist)
library(data.table)
nmlist <- lapply(l, names)
nm1 <- unlist(nmlist)
rbindlist(Map(setnames, l, relist(ave(nm1, phonetic(nm1),
FUN = function(x) x[1]), skeleton = nmlist)), fill = TRUE)
-输出
# apple orange dragonfruit pear
#1: 1 2 13 NA
#2: 2 3 14 NA
#3: 3 4 15 NA
#4: 7 6 2 1
#5: 8 7 3 2
#6: 9 8 4 3
【讨论】:
我从未见过语音,但在这里看到你的实现,这对于搞乱附加、合并和命名约定非常有用。谢谢! @fuzzydata 谢谢,你的预期输出是什么。你需要'梨'的列 我不需要这个应用程序中的“梨”列,但一般来说,提供一个版本的 rbindlist(lapply(filenames,fread, select = c (1:3))) 代码实际上允许使用 NA 添加新列(即 fill=TRUE)选项,同时使用列 #s 而不是名称,以免在拼写存在的地方创建重复列略有不同(假设所有列在 CSV 文件中的顺序相同)。您上面的代码似乎可以做到这一点,所以我注意到这一点以备将来使用,以防我需要添加的变量。以上是关于附加具有不同列数量和拼写的 csv的主要内容,如果未能解决你的问题,请参考以下文章