打开特定序列的csv:NA无处不在?

时间:2015-06-14 07:40:18

标签: r csv

我觉得这是一个相对简单的问题,我觉得我很接近,但我没有通过边缘案例测试。我有一个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:10id=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语句。任何见解将不胜感激! :)

3 个答案:

答案 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..)