我尝试使用fread()从csv中读取所选列。我发现我可以使用列号矢量,但不列名称。关于"选择"参数,文档只是说"要保留的列名或数字的向量,其余部分。"他们还提供了
的例子fread(data, select=c("A","D"))
因此,为什么我的代码会抛出下标超出范围错误?这是我的代码的要点,希望能够推广给其他用户:
test = data.frame(matrix(c(1:50),ncol = 5))
names(test) = c("A", "B", "C", "D", "E")
write.table(test, file = "/Users/me/Desktop/test.txt", sep = ",")
fread("/Users/me/Desktop/test.txt", sep = ",", header = TRUE, select = c("A","B"))
给予
Error in ans[[1]] : subscript out of bounds
但是,这会将第一列和行号作为列:
fread("/Users/me/Desktop/test.txt", sep = ",", header = TRUE, select = c(1,2))
1 1
1: 2 2
2: 3 3
3: 4 4
4: 5 5
5: 6 6
6: 7 7
7: 8 8
8: 9 9
9: 10 10
...而read.table()能够平稳地读取整个数据集:
read.table("/Users/me/Desktop/test.txt", sep = ",", header = TRUE)
A B C D E
1 1 11 21 31 41
2 2 12 22 32 42
3 3 13 23 33 43
4 4 14 24 34 44
5 5 15 25 35 45
6 6 16 26 36 46
7 7 17 27 37 47
8 8 18 28 38 48
9 9 19 29 39 49
10 10 20 30 40 50
rownames和标题显然正在发生,但我不确定如何解决它。我已尝试使用和不使用标题。我使用的数据集(不是在这个例子中)已经有了rownames,所以用rownames = FALSE重写它不是一个选项。
答案 0 :(得分:3)
此答案假设您的原始数据不是通过write.table()
生成的,您获得了一个文件并试图通过fread()
阅读(问题中也说明了这一点)。
我认为您遇到此问题是因为文件中的行名称。我还没有想出一个直接的方法来将fread()
应用于数据,但我认为这种解决方法是安全的,并且在效率方面不会让您付出太多代价。以下是步骤......
1)使用scan()
读取文件的第一行,并在开头添加一个额外的""
元素。这是为了使标题行偏移以考虑文件中的行名称。
nm <- c("", scan("test.txt", "", nlines = 1, sep = ","))
2)定义所需的列并在nm
中找到它们。而不是1和4,偏移现在给我们2和5并且说明行名称。
sel <- nm %in% c("A", "D")
3)从第二行开始读取文件(即没有标题),并在选择参数中使用sel
。
library(data.table)
dt <- fread("test.txt", skip = 1, select = which(sel))
4)现在我们已经读取了我们想要的数据,我们可以重置列名。
setnames(dt, nm[sel])[]
# A D
# 1: 1 31
# 2: 2 32
# 3: 3 33
# 4: 4 34
# 5: 5 35
# 6: 6 36
# 7: 7 37
# 8: 8 38
# 9: 9 39
# 10: 10 40
如果您提供的示例是对实际数据的良好表示,我不会发现任何无法解决的问题。希望它适合你。
答案 1 :(得分:1)
此示例说明了为什么您始终需要仔细检查您正在生成的文件的格式。 read.table
和fread
之间存在一些差异;这里的问题来自行名称以及它们是如何由write.table
编写的。一如既往,仔细阅读文档(?write.table
)会有很大帮助。
write.table
会写入行名称。但这是如何:
filename<-"somefilename.txt"
write.table(test, file = filename, sep = ",")
readLines(filename,2)
#[1] "\"A\",\"B\",\"C\",\"D\",\"E\""
#"\"1\",1,11,21,31,41"
我读了生成文件的前两行。仔细阅读它们,您可以看到这不是“标准”CSV。为什么?因为标题有4个逗号而“数据”行5.对于标准CSV,您应该在第一列名称之前加上逗号。这是通过在col.names=NA
中添加write.table
来实现的:
write.table(test, file = filename, sep = ",", col.names=NA)
#now works
fread(filename, sep = ",", header = TRUE, select = c("A","B"))
您现在可以查看并看到逗号作为文件的第一个字符出现。或者,您可以避免在row.names=FALSE
中写入write.table
的行名称,但这并不总是可行的,因为有时它们是有意义的。
答案 2 :(得分:-1)
library(data.table)
library(readr)
# save mtcars as CSV w/o row names or column names
write_csv(mtcars, "mtcars.csv", col_names=FALSE)
# read in the same file with fread but since we tell it
# to not use a header, we have to specify the column names
# the way fread will create them otherwise you get your error
fread("mtcars.csv", header=FALSE, select=c("V1", "V4"))
## V1 V4
## 1: 21.0 110
## 2: 21.0 110
## 3: 22.8 93
## 4: 21.4 110
## 5: 18.7 175
## 6: 18.1 105
# try again, this time keeping column names in the
# data file
write.csv(mtcars, file = "mtcars.csv", row.names=FALSE)
# now read it back in and select based on column names
# I picked different columns
head(fread("mtcars.csv", select=c("mpg", "qsec")))
## mpg qsec
## 1: 21.0 16.46
## 2: 21.0 17.02
## 3: 22.8 18.61
## 4: 21.4 19.44
## 5: 18.7 17.02
## 6: 18.1 20.2
答案 3 :(得分:-1)
问题不在你的恐惧中,而是在你的写作表中。 默认情况下,它会在第一列中写入每行的名称。看看写的文件。
试试这个:(明确表示不写row.names)
write.table(test, file = "/Users/me/Desktop/test.txt",
sep = ",", row.names=FALSE)
然后做你的恐惧()。它会起作用。