我正在处理具有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来准备我的文件?
答案 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"