我觉得这是一个相对简单的问题,我觉得我很接近,但我没有通过边缘案例测试。我有一个CSV目录,而不是阅读所有这些目录,我只想要其中一些。这些文件的格式类似于001.csv,002.csv,...,099.csv,100.csv,101.csv等,这有助于解释循环中的if()
逻辑。例如,要获取所有文件,我会执行以下操作:
id = 1:1000
setwd("D:/")
filenames = as.character(NULL)
for (i in id){
if(i < 10){
i <- paste("00",i,sep="")
}
else if(i < 100){
i <- paste("0",i,sep="")
}
filenames[[i]] <- paste(i,".csv", sep="")
}
y <- do.call("rbind", lapply(filenames, read.csv, header = TRUE))
以上代码适用于id=1:1000
,适用于id=1:10
,id=20:70
,但只要我传递id=99:100
或任何涉及数字从100开始的序列,它就会介绍了很多NAs。
id=98:99
> filenames
098 099
"098.csv" "099.csv"
id=99:100
> filenames
099
"099.csv" NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA
"100.csv"
我觉得我在if()
逻辑中错过了一些catch语句。任何见解将不胜感激! :)
答案 0 :(得分:3)
您可以避免创建filenames
filenames <- sprintf('%03d.csv', 1:1000)
y <- do.call(rbind, lapply(filenames, read.csv, header = TRUE))
答案 1 :(得分:2)
@akrun为您提供了更好的解决方案。但就你的代码的实际问题而言,问题是对于i&lt; 100您通过字符向量进行子集(使用paste
隐式转换),而对于i&gt; = 100,您按整数进行子集。当您使用id = 99:100
时,这会转换为:
filenames <- character(0)
filenames["099"] <- "099.csv" # length(filenames) == 1L
filenames[100] <- "100.csv" # length(filenames) == 100L, with all(filenames[2:99] == NA)
分配给尚未存在的矢量的命名成员将在位置length(vector) + 1
创建新成员,同时分配到&gt;的编号位置。 length(vector)
也将填写NA的每个干预职位。
答案 2 :(得分:1)
另一种方法虽然效率低于@ akrun的解决方案,但具有以下功能:
merged <- function(id = 1:332) {
df <- data.frame()
for(i in 1:length(id)){
add <- read.csv(sprintf('%03d.csv', id[i]))
df <- rbind(df,add)
}
df
}
现在,您可以将文件合并到:
dat <- merged(99:100)
此外,您可以通过在df
的最后一行之前的函数中插入以下行来指定列名:
colnames(df) <- c(..specify the colnames in here..)