【问题标题】:Remove empty columns from read_csv()从 read_csv() 中删除空列
【发布时间】:2016-06-29 00:19:38
【问题描述】:

我正在尝试使用 readr 包中的 read_csv() 读取链接到 here 的 csv 文件,然后删除空列。

如果我改用 read.csv(),则可以使用 8:12 轻松删除空列

library(dplyr)    
select(data, 1:7)

但是,当我使用 read_csv() 函数读取 csv 文件时,相同的代码会出错;

Error: found duplicated column name: NA, NA, NA, NA

如何删除这些空列?

正确命名空列以便我可以删除它们似乎没有意义。我更喜欢使用read_csv() 而不是read.csv(),因为它使以后的分析工作更轻松。

【问题讨论】:

  • 在那种情况下,有什么理由不使用这个data <- data[,c(1:7)]

标签: r dplyr readr


【解决方案1】:

你可以这样做:

data <- data[,apply(data, 2, function(x) { sum(!is.na(x)) > 0 })]

这将只保留不完全为NA 的列。

或者,如果你安装了 dplyr 0.5,你可以使用新的select_if 函数来达到同样的效果:

has_data <- function(x) { sum(!is.na(x)) > 0 }
data <- data %>% select_if(has_data)

【讨论】:

  • 这应该是一个内置的了。 2 年后?
【解决方案2】:

我不确定read_csv,但如果您使用read.csv,请将您不想要的列指定为“NULL”colClasses,您将得到您想要的(调整rep 调用中的整数根据需要:

read.csv( file = [yourfile],
        colClasses = c( rep("character",3), rep("NULL",5) )
)

上面将只返回前 3 列,而忽略后面的 5 列。

替代答案:
你试过fread吗?它有一个select 参数,可能对您有用,例如:

fread( [filename], select = c(1:3) )

它还具有比 read.csv 和 read_csv 快很多的好处。这是我拥有的特定文件的速度测试:

microbenchmark::microbenchmark( 
fread = {rangerdata2 <- data.table::fread( filename, select = c(1:3) )}, 
read.csv = {rangerdata2 <- utils::read.csv( file = filename )[,1:3]}, 
read_csv = {rangerdata2 <- readr::read_csv( file = filename )[,1:3]}, 
times = 1000)

Unit: milliseconds
 expr      min       lq      mean    median        uq      max neval cld
 fread    1.22161  1.32841  1.464724  1.377178  1.442089  14.57102  1000 a  
 read.csv 18.25402 18.55992 19.664278 18.772855 19.565684 34.87589  1000   c
 read_csv 13.43166 13.76704 14.615746 13.975987 14.608822 33.36244  1000  b 

【讨论】:

  • 要对freadread_csvread.csv 进行有效比较,您需要使用更大的文件。对于一个小文件,您主要比较的是调用函数所涉及的任何开销,而不是读取速度,并且所有三个函数都足够快,以至于差异不明显。我用一个 50 MB 的文件、100 万行、7 列(仍然相对较小,但对于此目的足够大)测试了这三个函数,时间为(以秒为单位):fread: 0.78read_csv: 1.05read.csv: 15.1。跨度>
  • 为了它,我在一台速度更快的计算机上测试了freadread_csv,它有 1000 万行、11 列、1.8 GB 的 csv 文件。基于 5 次重复的中位时间(以秒为单位):fread: 21.3read_csv: 23.0
  • 很公平,但对于我最常使用的文件,这些时间是相关的(是的,即使总数很小,任何改进都显得微不足道)。如果开销对总时间的贡献很大,那对我来说很重要。不过感谢您的测试,这绝对很有趣。
【解决方案3】:

一旦您的 csv 文件作为数据框加载到 R 中,您就可以这样做(假设您的数据框名为 dat):

dat = dat[, sapply(dat, function(i) !all(is.na(i)))]

最初,我在想,如果你使用read_csv,你可以这样做:

dat = dat[, !is.na(names(dat))]

因为read_csv 将所有空列的名称设置为NA。但是,这可能很危险。如果您在第一行中有一个没有名称的列,但有一些数据,则该列的名称也将是 NA 并且它也会被删除。

【讨论】:

    猜你喜欢
    • 2017-11-02
    • 2022-11-01
    • 2012-01-23
    • 1970-01-01
    • 2019-05-28
    • 2021-08-21
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多