如何在 `data.table::fread` 中同时使用 col.names 和 colClasses 参数?

3
作为一个简单的例子,我写出了没有列名的 cars
data.table::fwrite(cars, "cars.csv", col.names = FALSE)

然后我尝试通过指定列的名称和类型来读取它们 a

data.table::fread("cars.csv", col.names = c("a","b"),
                  colClasses = list(a = "numeric"))

然后我遇到了这个错误

在data.table :: fread("cars.csv", col.names = c("a", "b"),colClasses = list(a = "numeric"))中出错:colClasses [[1]] 中的列名'numeric'未找到

2个回答

4

一种可能的解决方案是使用列的索引而不是名称。

data.table::fread("cars.csv", col.names = c("a","b"), colClasses = list(numeric = 1))

似乎这是唯一的方法,但从用户角度来看很糟糕。 - xiaodai

1

看起来 data.table 在处理 colClasses 参数之前会处理 col.names。因此,除了其他答案提供的解决方法,还有两种替代方式:

# option1: A character vector of classes
fread("cars.csv", colClasses = c(V1 = "numeric"), col.names = c("a","b"))

# option2: Or a named list of vectors of column names or numbers
fread("cars.csv", colClasses = list(numeric = "V1"), col.names = c("a","b"))

在这里,V1 是第一列的自动检测名称。


这个解决方案仅适用于没有列名的数据,而“变通方法”也适用于具有列名的数据。我不认为“V1”相比使用1有任何改进,因为在两种情况下都需要知道列的位置。 - kath
@kath,我想要强调的主要点是解释为什么会出现这种错误。data.table先解析colClasses参数去读取数据,然后再设置列名。一旦我们知道了为什么,我们就知道该如何解决。两种替代方法只是次要点。我同意你的回答更加优雅。"V1"是自动检测的。如果数据有标题行,我们可以用标题行中对应的值来替换"V1"。 - mt1022

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