我有以下问题:
我的数据框看起来如下,即使它更大(20GB):
Letters <- c("A","B","C")
Numbers <- c(1,0,1)
Numbers <- as.integer(Numbers)
Data.Frame <- data.frame(Letters,Numbers)
现在我想为字母创建一个虚拟变量并编写以下for循环:
for(level in unique(Data.Frame$Letters)){Data.Frame[paste("", level, sep = "")]
<- ifelse(Data.Frame$Letters == level, 1, 0)}
因为我的数据帧太大,但执行时间很长。我尝试的另一种可能的解决方案是:
factors <- model.matrix(~Letters-1, data=Data.Frame)
cbind(Data.Frame, factors)
结果是一样的,但是当我在更大的数据框架上使用它时,它需要更长的时间。
是否有任何可能的替代方案,这将导致相同的解决方案并且计算速度更快?
非常感谢您提前!
答案 0 :(得分:1)
如果你有足够的内存,你可以试试这个:
n <- 18e6
set.seed(31)
d <- data.frame(Letters = as.factor(sample.int(1.3e4, n, replace = T)),
Numbers = sample.int(30, n, replace = T))
require(data.table)
dt <- as.data.table(d)
x2 <- as.integer(dt$Letters)
ilist <- unique(x2)[1:20] # for test 20 cols
for (i in ilist) {
set(dt, j = as.character(i), value = (x2 == i) + 0L)
}
否则,您应该按照其他用户的建议使用稀疏矩阵:
require(Matrix)
dd <- sparse.model.matrix(~ Letters - 1, data = d)
dd[1:5, 1:5]
# 5 x 5 sparse Matrix of class "dgCMatrix"
# Letters1 Letters2 Letters3 Letters4 Letters5
# 1 . . . . .
# 2 . . . . .
# 3 . . . . .
# 4 . . . . .
# 5 . . . . .
答案 1 :(得分:1)
您可以使用dcast.data.table
包中的data.table
dt <- data.table(Letters,Numbers)
dcast.data.table(dt, Letters+Numbers~Letters,fun.aggregate=length)
Letters Numbers A B C
1: A 1 1 0 0
2: B 0 0 1 0
3: C 1 0 0 1
答案 2 :(得分:-1)
data.table
可能更快?
怎么样?
Letters <- c("A","B","C","C")
Numbers <- c(1,0,1,2)
Numbers <- as.integer(Numbers)
Data.Frame <- data.frame(Letters,Numbers)
library(data.table)
DT <- as.data.table(Data.Frame)
Letters <- unique(DT$Letters)
for(l in Letters){
DT[, (l):=as.integer(Letters==l)]
}
> DT
Letters Numbers A B C
1: A 1 1 0 0
2: B 0 0 1 0
3: C 1 0 0 1
4: C 2 0 0 1