我在dplyr github page 上发布了一个问题。我可以使用下面的代码重现结果。它与 csv 是否包含一列没有标题的行名有关。 read_csv 和 read.csv 以不同方式处理此问题,因此与 filter 产生不同的结果。
首当其冲的情况
write_csv 到 read_csv 或 read.csv;两者都适用于filter
library(readr)
library(dplyr)
mtcars %>% write_csv("~/Desktop/test.csv")
test_r <- read_csv("~/Desktop/test.csv") %>% filter(hp>100)
test.r <- read.csv("~/Desktop/test.csv") %>% filter(hp>100)
现在是失败的时候
当通过write.csv 之类的过程生成 csv 时,除非该人将默认的 row.names 更改为 FALSE,否则它会引入一列不带标题的行名。在读回数据时,read_csv 不会填充行名所在的标题,但read.csv 会计算一个 X。因此,当filter 处理read.csv 导入时,它的所有标题都带有填充单元格,但是filter 在read_csv 之后至少在行名所在的位置有一个空的标题单元格。
test1_r %>% filter(hp>100) 之后的以下代码应该会出错,并出现以下错误
Error in filter_impl(.data, dots) :
attempt to use zero-length variable name
同样,最大的区别在于 write.csv 如何生成 csv。
mtcars %>% write.csv("~/Desktop/test1.csv")
test1_r <- read_csv("~/Desktop/test1.csv")
test1_r %>% str()
#should fail here
test1_r %>% filter(hp>100)
test1.r <- read.csv("~/Desktop/test1.csv")
test1.r %>% str()
test1.r %>% filter(hp>100)
要解决这个问题,您可以使用@hackR 上面提到的read.csv。或者,当您知道 csv 的行为如下时,您可以对第一列进行子集化:
test1_r <- read_csv("~/Desktop/test1.csv")[-1]
或者,如果您可以控制 csv 创建步骤,则可以将选项 row.names=FALSE 添加到 write.csv
mtcars %>% write.csv("~/Desktop/test2.csv", row.names = FALSE)
test2.r <- read_csv("~/Desktop/test2.csv")
test2.r %>% str()
test2.r%>% filter(hp>100)
或如上所示使用write_csv。