仅从R中的.csv文件每N行导入一次
只是一个简单的问题。是否有一种方法可以使用read.csv从大文件中每隔N行导入一次: 例如,一个5000-6000万行的文件,其中只需要从第2行开始每隔第4行使用一次 我考虑过可能合并'seq'函数,但我不确定这是否可行 有什么建议吗仅从R中的.csv文件每N行导入一次,r,csv,text,import,R,Csv,Text,Import,只是一个简单的问题。是否有一种方法可以使用read.csv从大文件中每隔N行导入一次: 例如,一个5000-6000万行的文件,其中只需要从第2行开始每隔第4行使用一次 我考虑过可能合并'seq'函数,但我不确定这是否可行 有什么建议吗 read.csv("filename.csv")[c(FALSE, TRUE, FALSE, FALSE), ] 我会成功的 这是因为逻辑向量被循环使用,直到它与read.csv返回的数据帧行数匹配为止。对于大型数据文件,最好的选择是在将不必要的行导入R之前过
read.csv("filename.csv")[c(FALSE, TRUE, FALSE, FALSE), ]
我会成功的
这是因为逻辑向量被循环使用,直到它与
read.csv
返回的数据帧行数匹配为止。对于大型数据文件,最好的选择是在将不必要的行导入R之前过滤掉。最简单的方法是通过操作系统命令,如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
write.csv(1:1000,file='test.csv')
file.pipeSven为中等大小的文件提供了一个很好的答案。但是,如果您这样做的原因是因为读取整个文件不适合内存,那么您需要采取不同的方法
使用Perl或AWK等外部工具对文件进行预处理可能是最简单的方法,以便只包含所需的行,您可以使用pipe
读取另一个程序的输出,这样就不必创建中间文件
另一种方法是将文件传输到数据库,然后仅从数据库中选择所需的行
您还可以循环浏览该文件。如果显式打开该文件,则可以一次读取几行,只保留所需的行,然后从停止处开始读取下一个块。read.csv
的选项可以跳过行并限制要读取的行数。正如@df239所建议的,最好事先使用命令行工具筛选行
下面是一个使用sed
的简单版本:
df <- read.csv(pipe("sed -n '2~4p' test.csv"))
df虽然sed
和awk
解决方案很好,但最好在R
本身内这样做(比如在Windows机器上,或者避免GNUsed
与BSDsed
的差异)。使用从tidyverse
到每n行进行采样的
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()
}
请注意,这会将整个文件读入内存,并将其转换为数据帧,然后丢弃您不需要的四分之三的数据。对于中等大小的文件,这是一种很好的方法,但是如果您这样做是因为文件太大而无法放入内存,那么此方法将不起作用。从第二行开始,您只需将i%4==0
更改为i%4==2
。因此,我尝试了此操作,并得到了以下错误:error in read.table(file=file,header=header,sep=sep,quote=quote,:Input中没有可用的行您运行的是什么系统?OSX 10.9.1 R Studio版本0.98.490Ahh,mac上的sed
不喜欢2~4p
。我实际上不知道如何修复它。请尝试gsed
,如果安装了,它会工作的。不用担心,伙计。谢谢!感谢您提供与Windows兼容的解决方案!很长一段时间以来,我都没有意识到管道在这个操作系统上无法直接工作。
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