【问题标题】:Why this R list of lists fails?为什么这个 R 列表列表失败了?
【发布时间】:2016-10-29 23:21:37
【问题描述】:

我有一个 .CSV 文件名列表,我想将其内容作为数组mA 读入内存,即我想将一个数组/列表放入mA 的单元格中,以便制作和访问列表列表或数组数组。

data = read.csv("/home/masi/dataList.csv",header = FALSE,sep = ",") 
# P103C1.csv
# P103C2.csv 
# ...

i = 1
# http://stackoverflow.com/a/5688126/54964
mA <- vector("list", length(data))
for (d in data)
        data[i] = paste("/home/masi/Documents/CSV/", d, sep="") 
        # /home/masi/Documents/CSV/P103C1.csv
        # /home/masi/Documents/CSV/P103C2.csv
        # ...

        tmp = read.csv(data[i],header = TRUE,sep = ",")

        # http://stackoverflow.com/a/10776795/54964
        mA[i] = list(tmp[, 1]) # attempt to make a list of lists

        i = i + 1
end

错误

function (x, ...) 
UseMethod("end")
<bytecode: 0x28cb7f8>
<environment: namespace:stats>
function (x, ...) 
UseMethod("end")
<bytecode: 0x28cb7f8>
<environment: namespace:stats>

代码 2

data = scan(file = "/home/masi/dataList.csv", what = character()) # vector, access data[i]
files <- vector("list", length(data))

str(data)

for (i in 1:length(data)) {
        tmp = paste0("/home/masi/Documents/CSV/", data[i]) # faster than paste sep=""

        print(i)

        tmp # does not work

        tmp = read.csv(tmp, header = FALSE, sep=","); # no header with other approach
#       files[[i]] = list(tmp[, 1])
}

tmp # works if last tmp is commented out

dataList.csv

P103C1.csv
P103C2.csv
P111C1.csv
P111C2.csv
P118C1.csv

P103C1.csv

-0.04,-0.19
-0.045,-0.58
-0.04,-0.465
-0.035,-0.39
-0.01,-0.24

i=23 发生错误时的输出

Read 31 items
 chr [1:31] "P103C1.csv" "P103C2.csv" "P111C1.csv" "P111C2.csv" ...
...
[1] 21
[1] 22
[1] 23
Error in read.table(file = file, header = header, sep = sep, quote = quote,  : 
  no lines available in input
Calls: read.csv -> read.table
Execution halted

操作系统:Debian 8.5
R:3.1.1
Linux 内核:4.6 反向移植
硬件:华硕 Zenbook UX303UA

【问题讨论】:

标签: arrays r list


【解决方案1】:

这里出了三件事:

所以解决方法是

filelst = scan(file = "/home/masi/dataList.csv", what = character()) 
i = 1
mA <- vector("list", length(filelst))
for (file in filelst) {
  tmp = paste0("/home/masi/Documents/CSV/", file)
  tmp = read.csv(tmp, header = TRUE)
  mA[[i]] = list(tmp[, 1])
  i = i + 1
  }

跟进

(老实说,我认为这应该是一个新问题,关于读取文件的安全且健壮的代码。)

根据您的更新,某些文件可能为空。为了让代码更健壮,我们需要try:

filelst = scan(file = "/home/masi/dataList.csv", what = character()) 
i = 1
mA <- vector("list", length(filelst))
for (file in filelst) {
  tmp = paste0("/home/masi/Documents/CSV/", file)
  test <- try(read.csv(tmp, header = TRUE), silent = TRUE)
  if (class(test) == "try-error") mA[[i]] = "Empty File; No Read!"
  else mA[[i]] = list(test[, 1])
  i = i + 1
  }

阅读?try,并考虑使用以下玩具示例:

x <- ""
y <- "-0.04,-0.19
      -0.045,-0.58
      -0.04,-0.465
      -0.035,-0.39
      -0.01,-0.24"

tmp <- try(read.csv(text = x, header = FALSE), silent = TRUE)
tmp
#[1] "Error in read.table(file = file, header = header, sep = sep, quote = quote,  : \n  no lines available in input\n"
#attr(,"class")
#[1] "try-error"
#attr(,"condition")
#<simpleError in read.table(file = file, header = header, sep = sep, quote = quote,     dec = dec, fill = fill, comment.char = comment.char, ...): no lines available in input>

tmp <- try(read.csv(text = y, header = FALSE), silent = TRUE)
tmp
#      V1     V2
#1 -0.040 -0.190
#2 -0.045 -0.580
#3 -0.040 -0.465
#4 -0.035 -0.390
#5 -0.010 -0.240

【讨论】:

  • 我将您的 if-else 结构更改为更明确,如果文件丢失会立即停止 if (class(test) == "try-error") { stop(sprintf("Empty file \"%d\".", i)); } else { files[[i]] = test; }
猜你喜欢
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多