我有一个超过3 GB的大数据框(2628x670316),并想在每一行使用sum函数。
数据文件看起来像这样只包含0s,1s和2s。
0 1 2 0 0 0 0 0 0 1 1 1 ...
0 1 0 0 0 0 2 2 2 2 2 2 ...
.
.
.
当我运行sum(data [1,] == 0)时,这需要很长时间。有没有更快的方法呢?
提前谢谢。
PS。我想使用sum的原因是因为我想在每一行上获得0s,1s和2s的百分比。如果有另一种方法可以做到这一点,那么这个答案也会有所帮助。
答案 0 :(得分:3)
如果df
是您的data.frame:
t(apply(df,1,table))*100/ncol(df)
将为每行提供0s,1s和2s的百分比。
(你避免进行比较,这可能需要很长时间......)
数据:
set.seed(13)
df<-data.frame(matrix(sample(c(0,1,2),500,T),nrow=10))
t(apply(df,1,table))*100/ncol(df)
为您提供:
0 1 2
[1,] 34 44 22
[2,] 38 40 22
[3,] 28 34 38
[4,] 26 38 36
[5,] 36 42 22
[6,] 30 32 38
[7,] 42 26 32
[8,] 30 36 34
[9,] 36 24 40
[10,] 24 34 42
编辑感谢@akrun的评论:
如果每行都没有表示所有可能的值(0,1,2),则必须执行以下操作:
t(apply(df, 1, function(x) table(factor(x, levels=0:2))))*100/ncol(df)
答案 1 :(得分:2)
如果数据都是整数,那么将它表示为矩阵m
要快得多(这在语义上也更接近于数据的实际情况 - 具有同质性的矩形数据集合类型,而不是可能不同类型的列),可能使用scan()
输入。使用矩阵,列操作比行操作更快,因此使用t(m)
转置它。 tabulate()
函数比table()
快得多,但在目前情况下稍微挑剔一点
nonZeroCounts <- apply(t(m), 2, tabulate, max(m))
更详细地说,这里是提出的解决方案
f0 <- function(df)
t(apply(df, 1, table))
f1 <- function(m) {
n <- t(apply(t(m), 2, tabulate, max(m)))
ans <- cbind(ncol(m) - as.integer(rowSums(n)), n)
colnames(ans) <- 0:max(m)
ans
}
一些数据
nrow <- 100; ncol <- floor(nrow * 670316 / 2628)
m <- matrix(sample(0:2, nrow * ncol, TRUE), nrow=nrow)
df <- as.data.frame(m)
和基本比较
> system.time(ans0 <- f0(df))
user system elapsed
1.082 0.000 1.083
> system.time(ans1 <- f1(m))
user system elapsed
0.052 0.000 0.052
> identical(ans0, ans1)
[1] TRUE
或nrow=1000
> system.time(ans1 <- f1(m))
user system elapsed
6.521 1.461 7.984
> system.time(ans0 <- f0(df)) ## argh, boring, stop after 1.5 minutes!
C-c C-c
Timing stopped at: 93.608 2.752 96.325
答案 2 :(得分:0)
尝试rowSums
,也许它更快
test<-data.frame(V1=c(1,1,1,1), V2=c(2,2,2,0))
rowSums(test)
我怀疑你能获得比香草和更快的和函数。
获得总和的另一种方法是臭名昭着的apply函数族
apply(test, 1, sum)
一些测试和rowSums
是否相当快
set.seed(13)
df<-data.frame(matrix(sample(c(0,1,2),500000000,T),nrow=2000))
system.time(rowSums(df))
system.time(rowSums(df))
user system elapsed
8.00 0.68 8.69
而apply
system.time(apply(df, 1, sum))
user system elapsed
81.67 5.99 87.96