使用read.table我想只将我的第六行文件加载到R中

时间:2014-05-08 07:21:56

标签: r

我正在处理具有10分钟经度/纬度值的轨迹文件。但是我想只将每小时值加载到R.

我当前的代码将所有文件加载到R:

beussel.trajectories<- lapply(beusselstr.trajectory_files,read.table,
                          sep="",header=TRUE,skip=1,fill=TRUE,fileEncoding="latin1")

beusselstr.trajectory_files是一个包含329个文件的文件夹,我有10个其他文件夹,文件数量相同。然后这些文件在4天内有10分钟的值向后反转,因此每个文件有21318行。

我在这里上传了一天文件https://www.dropbox.com/s/tp2d9lr7xawuvr4/Beusselstr_001_020710.txt

加载所有这些都需要很长时间,因为我的计算机内存量相当少,R不断给我错误,R不能分配125kb的矢量。

这实际上是可行的还是我必须使用其他东西,比如Fortran来准备我的文件?

3 个答案:

答案 0 :(得分:2)

如果您只想读取每第六行,您可以跳过前六行(包括标题)并且只读取一行,然后跳过前十二行并读入一行,等等。您可以使用嵌套lapply

  beussel.trajectories <- lapply(beusselstr.trajectory_files,function(x) {do.call(rbind,lapply(seq(6,21318,by=6),function(y) read.table(x,sep="",header=F,fileEncoding="latin1",skip=y,nrow=1)))})

您可以稍后添加列名称。

这是一个可重复的例子。它很慢,但是如果你先将文件保存在计算机上,它的运行速度会快很多。

df <- lapply('http://statland.org/R/RC/heartatk4R.txt', function(x) {do.call(rbind,lapply(seq(6,600,by=6),function(y) read.table(x,header=F,colClasses = c("character"),skip=y,nrows=1)))})
head(df[[1]])

#  V1    V2 V3  V4 V5        V6   V7  V8
#1  6 41091  M 121  0 6378.6400 0009 084
#2 12 41091  M 121  0 3930.6300 0005 072
#3 18 41091  M 121  0 4989.7100 0005 056
#4 24 41071  M 121  0 6297.7200 0006 073
#5 30 41011  M 122  0 9862.9000 0002 038
#6 36 41041  F 121  0 2584.1000 0009 081

答案 1 :(得分:1)

这是一个有点重复的问题,请参阅here

无论如何,更快的方法是使用data.table :: fread()完整地读取每个文件,然后对结果进行子集化。

library(plyr)
library(dplyr)
library(data.table)
library(microbenchmark)

# create a sample file
my_large_file <- 
    data_frame(
        var_every_six = rep(1:6, length.out = 250e3),
        num_var = rnorm(250e3),
        char_var = rep(letters, length.out = 250e3),
        char_var2 = rep(state.abb, length.out = 250e3)  
    )

# export to csv
write.csv(my_large_file, 'my_large_file.csv', row.names = F)

# compare reading and subsetting with fread()/data.table method with read.table() method
microbenchmark(
    {
        my_csv = fread('my_large_file.csv')
        my_csv_sub = my_csv[my_csv$var_every_six == 6, ]    
    }, 
    {   
        my_csv = read.csv('my_large_file.csv')
        my_csv_sub = my_csv[my_csv$var_every_six == 6, ]        
    }
)

# Unit: milliseconds
                                                                                                # expr
    # {     my_csv = fread("my_large_file.csv")     my_csv_sub = my_csv[my_csv$var_every_six == 6, ] }
 # {     my_csv = read.csv("my_large_file.csv")     my_csv_sub = my_csv[my_csv$var_every_six == 6, ] }
      # min       lq     mean   median       uq      max neval
 # 201.7967 210.1511 220.8584 216.2771 225.5729 291.8267   100
 # 574.0465 629.9268 655.1687 654.8691 682.1258 809.9981   100

即使使用超级简单的.csv,data.table方法也快3倍。 fread()的性能提升通常会随着更大和更复杂的文件而增加。

答案 2 :(得分:0)

也许首先使用合适的工具预处理文件。例如,如果使用linux

awk 'NR%6==2' /input/file  

> write(1:100, 'test.txt', sep = '\n')
> system("awk 'NR%6==2' test.txt > test1.txt")
> readLines('test1.txt')
 [1] "2"  "8"  "14" "20" "26" "32" "38" "44" "50" "56" "62" "68" "74" "80" "86"
[16] "92" "98"