仅从R中的.csv文件导入每第N行

时间:2014-02-19 20:35:46

标签: r csv text import

只是一个简单的问题。有没有办法使用read.csv从大文件中导入每个第N行:

示例,一个50-60万行文件,其中您只需要从第2行开始的每第4行。

我想过可能会加入'seq'功能,但我不确定这是否可行。

有什么建议吗?

5 个答案:

答案 0 :(得分:14)

对于大型数据文件,最好的选择是在导入R之前过滤掉不必要的行。最简单的方法是通过OS命令,如sed,awk,grep等。以下代码从文件中读取每4行:例如:

write.csv(1:1000, file='test.csv')

file.pipe <- pipe("awk 'BEGIN{i=0}{i++;if (i%4==0) print $1}' < test.csv ")
res <- read.csv(file.pipe)
res

> res
     X3 X3.1
1     7    7
2    11   11
3    15   15
4    19   19
5    23   23
6    27   27
7    31   31
8    35   35

答案 1 :(得分:5)

read.csv("filename.csv")[c(FALSE, TRUE, FALSE, FALSE), ]

会做到这一点。

这是有效的,因为逻辑向量被回收,直到它与read.csv返回的数据帧的行数相匹配。

答案 2 :(得分:4)

正如@ df239建议的那样,使用命令行工具预先过滤行要好得多。

以下是使用sed的简单版本:

df <- read.csv(pipe("sed -n '2~4p' test.csv")) 

2~4p告诉sed从第2行开始每隔4行。

答案 3 :(得分:1)

Sven为中等大小的文件提供了很好的答案。但是,如果您这样做的原因是因为读取整个文件并不适合内存,那么您需要采取不同的方法。

使用像Perl或AWK这样的外部工具来预处理文件只能拥有你想要的行可能是最简单的,你可以使用pipe从另一个程序的输出中读取,这样你就不会必须创建一个中间文件。

另一种方法是将文件传输到数据库,然后只从数据库中选择所需的行。

您也可以循环浏览该文件。如果你明确地打开文件,那么你可以一次读取几行,只保留你想要的那些行,然后从你离开的地方开始读取下一个块。 read.csv跳过行并限制要读取的行数的选项在这里会有所帮助。

答案 4 :(得分:1)

尽管sedawk解决方案很棒,但最好在R本身内完成此操作(例如在Windows机器上,或者避免使用GNU sed vs BSD sed个差异)。将tidyverse中的readr::read_*_chunkedcallback一起对每行nth进行采样的https://github.com/poetix/protonpack一起使用,效果很好:

read_tsv_sample <- function(fn, nth, ...) {
  sample_df_cb <- function(df, idx) {
    df[seq(1, nrow(df), nth), ]
  }

  read_tsv_chunked(fn,
                   ...,
                   chunk_size = 10000,
                   callback = DataFrameCallback$new(sample_df_cb)
  ) %>%
    bind_rows()
}

例如...

iris %>% write_tsv("iris.tsv")

iris %>% dim
#> [1] 150   5

"iris.tsv" %>%
    read_tsv_sample(10,
                    col_types = cols(.default = col_double())
                    ) %>%
    dim
#> [1] 15  5