更新
我的原始帖子有一个错误的表述:
通过 rownames
和 colnames
进行索引的问题在于,你需要针对每个元素运行一次向量/线性扫描,例如,你需要查找每一行来查看哪一行被命名为“36”,然后重新开始查找以寻找“34”。
Simon 在这里的评论中指出,R 显然使用哈希表进行索引。对于我的错误,我感到非常抱歉。
原始答案
请注意,本答案中的建议假定您具有数据的非重叠子集。
如果您想保留列表查找策略,我建议存储实际的行索引而不是字符串名称。
另一种方法是将您的“组”信息存储为 data.frame
的另一列,然后根据其组拆分 data.frame
,例如,假设您重新编码的 data.frame
如下:
dat <- data.frame(a=sample(100, 10),
b=rnorm(10),
group=sample(c('a', 'b', 'c'), 10, replace=TRUE))
你可以这样做:
然后你可以执行:
split(dat, dat$group)
$a
a b group
2 66 -0.08721261 a
9 62 -1.34114792 a
$b
a b group
1 32 0.9719442 b
5 79 -1.0204179 b
6 83 -1.7645829 b
7 73 0.4261097 b
10 44 -0.1160913 b
$c
a b group
3 77 0.2313654 c
4 74 -0.8637770 c
8 29 1.0046095 c
或者,根据你想要用“splits”做什么,你可以将你的data.frame
转换为一个data.table
,并将其键设置为新的group
列:
library(data.table)
dat <- data.table(dat, key="group")
现在进行列表操作,这将会给你和上面使用的
split
函数相同的结果。
x <- lapply(unique(dat$group), function(g) dat[J(g),])
但是你可能想要“改进你的调试”,可以使用行内方式实现,例如:
ans <- dat[, {
list(nrow=length(a), mean.a=mean(a), mean.b=mean(b))
}, by="group"]
ans
group nrow mean.a mean.b
[1,] a 2 64.0 -0.7141803
[2,] b 5 62.2 -0.3006076
[3,] c 3 60.0 0.1240660
您可以使用plyr
以类似的方式完成最后一步,例如:
library(plyr)
ddply(dat, "group", summarize, nrow=length(a), mean.a=mean(a),
mean.b=mean(b))
group nrow mean.a mean.b
1 a 2 64.0 -0.7141803
2 b 5 62.2 -0.3006076
3 c 3 60.0 0.1240660
但是既然你提到你的数据集相当大,我认为你会喜欢data.table
提供的速度提升。
rows
里有多少元素,rows[[i]]
中大概有多少元素吗?另外,你的rownames
都是唯一的对吗?(我构造了一个随机的dat
,30000x50,但是我似乎得到了很快的rows
时间,可能是我的数据不够大?) - mathematical.coffeerows
大约有 15000 个元素;length(rows[[i]])
的取值范围为 1 到 50。 - Jack Tanner