【问题标题】:automatically convert NAs to 0 while reading CSV读取 CSV 时自动将 NA 转换为 0
【发布时间】:2014-01-03 17:00:23
【问题描述】:

为了节省空间,我从 CSV 文件中省略了零作为一种稀疏表示(所有数据都是数字):

table = read.csv(text = "
V1,V2,V3
0.3,1.2,1.5
0.5,,2.1
,.1,")

这是我得到的:

> table

   V1  V2  V3
1 0.3 1.2 1.5
2 0.5  NA 2.1
3  NA 0.1  NA

我可以继续将 NA 更改为 0:

table[is.na(table)] = 0

    V1  V2  V3
1: 0.3 1.2 1.5
2: 0.5 0.0 2.1
3: 0.0 0.1 0.0

只是想知道在读入时是否有一个单行来执行此操作,最好使用 data.table 的 fread?:

table = fread("
V1,V2,V3
0.3,1.2,1.5
0.5,,2.1
,.1,")

更多信息:我想避免的原因

table[is.na(table)] = 0

虽然我的数据上的 fread 真的很快,但这个操作却很慢! (不知道为什么。)我的数据集是 336 行 x 3939 列。 (G. Grothendieck 的自定义类答案很快,感谢您的想法!)

【问题讨论】:

标签: r csv data.table


【解决方案1】:

设置一个将空字段视为 0 的自定义类。鉴于设置它只有一行 read.csv 语句来读取数据:

# test data
Lines <- "V1,V2,V3
0.3,1.2,1.5
0.5,,2.1
,.1,
"

# set up custom class
setClass("empty.is.0")
setAs("character", "empty.is.0", 
      function(from) replace(as.numeric(from), from == "", 0))

# one liner
read.csv(text = Lines, strip.white = TRUE, colClasses = "empty.is.0")

【讨论】:

    【解决方案2】:

    如果这是你经常做的事情,只需制作一个包装函数来读取它,然后转换 NA。

    my_read = function(..., replace=0) {
      data = fread(...)
      data[is.na(data)] = replace
      data
    }
    

    或者如果您想更通用并为任何功能工作

    my_gen_read = function(..., FUN="fread", replace=0) {
      FUN = match.fun(FUN)
      data = FUN(...)
      data[is.na(data)] = replace
      data
    }
    

    【讨论】:

      【解决方案3】:

      我建议使用标准压缩工具而不是自己创建:

      dt = data.table(a = 1:10) # your data.table
      
      zf = gzfile('filename.gz', 'w') # or bzfile or xzfile
      write.csv(dt, zf, quote = F, row.names = F)
      close(zf)
      
      # then read either with read.csv or fread (version 1.8.11+)
      df = read.csv('filename.gz')
      dt = fread('zcat filename.gz')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 2014-01-30
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        相关资源
        最近更新 更多