假设我有一个巨大的m * n矩阵X
(太大而无法读入内存)和二进制数字向量V
,长度为m
。我的目标是将与X
等于V
{而非1
对应的V[i] == 0
行(而不是与data table
相对应的行)读入专用matrix
/ {{ 1}}通过包,例如(但不一定相同)bigmemory
或ff
。仅适用于与V[i] == 1
对应的行。
这可以通过nrows
中的skip
和read.table
等方式进行,但我正在寻找bigmemory
,ff
等人。因RAM不足而输入解决方案。
这是一个MWE,它不能反映我X
的真实大小。
X <- array(rnorm(100*5),dim=c(100,5))
write.csv(X,"target.csv")
V <- sample(c(rep(1,50),rep(0,50))) #Only want to read in half the rows corresponding to 1's
rm(X)
#Now ... How to read "target.csv"?
答案 0 :(得分:3)
如何使用命令行工具sed
,构建一个命令,该命令沿着您要在命令中读取的行传递。我不确定这是否会有一些命令长度限制...
# Check the data
head( X )
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0.2588798 0.42229528 0.4469073 1.0684309 1.35519389
#[2,] 1.0267562 0.80299223 -0.2768111 -0.7017247 -0.06575137
#[3,] 1.0110365 -0.36998260 -0.8543176 1.6237827 -1.33320291
#[4,] 1.5968757 2.13831188 0.6978655 -0.5697239 -1.53799156
#[5,] 0.1284392 0.55596342 0.6919573 0.6558735 -1.69494827
#[6,] -0.2406540 -0.04807381 -1.1265165 -0.9917737 0.31186670
# Check V, note row 6 above should be skipped according to this....
head(V)
# [1] 1 1 1 1 1 0
# Get line numbers we want to read
head( which( V == 1 ) )
# [1] 1 2 3 4 5 7
# Read the first 5 lines where V == '1' in your example (remembering to include an extra line for the header row, hence the +1 in 'which()')
read.csv( pipe( paste0("sed -n '" , paste0( c( 1 , which( V == 1 )[1:6] + 1 ) , collapse = "p; " ) , "p' C:/Data/target.csv" , collapse = "" ) ) , head=TRUE)
# X V1 V2 V3 V4 V5
#1 1 0.2588798 0.4222953 0.4469073 1.0684309 1.35519389
#2 2 1.0267562 0.8029922 -0.2768111 -0.7017247 -0.06575137
#3 3 1.0110365 -0.3699826 -0.8543176 1.6237827 -1.33320291
#4 4 1.5968757 2.1383119 0.6978655 -0.5697239 -1.53799156
#5 5 0.1284392 0.5559634 0.6919573 0.6558735 -1.69494827
#6 7 0.6856038 0.1082029 0.1523561 -1.4147429 -0.64041290
我们实际传递给sed
的命令是......
"sed -n '1p; 2p; 3p; 4p; 5p; 6p; 8p' C:/Data/target.csv"
我们使用-n
来关闭任何行的打印,然后我们使用我们想要读取的行号的分号分隔向量,由which( V == 1 )
给出,最后目标文件名。请记住,这些行号已被+1
抵消,以说明构成标题行的行。
答案 1 :(得分:1)
ffdfindexget
包的 ff
正是您所寻找的:
函数ffdfindexget允许从ffdf data.frame中提取行 根据存储在ff向量中的正整数suscripts。
所以在你的例子中:
write.csv(X,"target.csv")
d <- read.csv.ffdf(file="target.csv")
i <- ff(which(V==1))
di <- ffdfindexget(d, i)
答案 2 :(得分:0)
一个可行的策略是将CSV文件导入数据库(R支持与大多数数据库的连接。如果您感觉前沿和速度很重要,请使用MonetDB;否则SQLite或其他任何方便。)
然后,您可以使用SQL指定适当的子集,并将其读入R。
答案 3 :(得分:0)
我认为你可以使用sqldf
包来实现你想要的。
sqldf
将csv文件直接读入SQLlite数据库,完全绕过R环境。
library(sqldf)
Xfile <- file('target.csv')
sqlcmd <- paste0('select * from Xfile where rowid in (', paste(which(V==1), collapse=','), ')')
sqldf(sqlcmd, file.format=list(header=TRUE))
或:
library(sqldf)
Vdf <- data.frame(V)
sqlcmd <- "select file.* from file, Vdf on file.rowid = Vdf.rowid and V = 1"
read.csv.sql("target.csv", sql = sqlcmd)