直接在R中的稀疏矩阵中创建虚拟变量集

ago*_*ken 5 r matrix sparse-matrix r-factor

假设您有一个包含大量列的数据框(1000个因子,每个因子有15个级别).您想创建一个虚拟变量数据集,但由于它太稀疏,您希望以稀疏矩阵格式保留虚拟变量.

我的数据集很大,步骤越少,对我来说就越好.我知道如何做上述步骤; 但我无法直接从初始数据集创建稀疏矩阵,即只有一步而不是两步.有任何想法吗?

编辑:一些评论要求进一步阐述,所以在这里:

其中X是我的原始数据集,包含1000列和50000条记录,每列有15个级别,

步骤1:使用类似代码从原始数据集创建虚拟变量;

# Creating dummy data set with empty values
dummified <- matrix(NA,nrow(X),15*ncol(X))
# Adding values to this data set for each column and each level within columns
for (i in 1:ncol(X)){colFactr <- factor(X[,i],exclude=NULL)
  for (j in 1:l){
    lvl <- levels(colFactr)[j]
    indx <- ((i-1)*l)+j
    dummified[,indx] <- ifelse(colFactr==lvl,1,0)
  }
}
Run Code Online (Sandbox Code Playgroud)

第二步:将巨大的矩阵转换为稀疏矩阵,代码如下;

sparse.dummified <- sparseMatrix(dummified)
Run Code Online (Sandbox Code Playgroud)

但是这种方法仍然创造了这个临时大矩阵,这需要大量的时间和内存,因此我要求直接的方法(如果有的话).

flo*_*del 9

感谢你澄清了你的问题,试试这个.

以下是具有两列的示例数据,这两列分别具有三个和两个级别:

set.seed(123)
n <- 6
df <- data.frame(x = sample(c("A", "B", "C"), n, TRUE),
                 y = sample(c("D", "E"),      n, TRUE))
#   x y
# 1 A E
# 2 C E
# 3 B E
# 4 C D
# 5 C E
# 6 A D

library(Matrix)
spm <- lapply(df, function(j)sparseMatrix(i = seq_along(j),
                                          j = as.integer(j), x = 1))
do.call(cBind, spm)
# 6 x 5 sparse Matrix of class "dgCMatrix"
#               
# [1,] 1 . . . 1
# [2,] . . 1 . 1
# [3,] . 1 . . 1
# [4,] . . 1 1 .
# [5,] . . 1 . 1
# [6,] 1 . . 1 .
Run Code Online (Sandbox Code Playgroud)

编辑:@ user20650指出do.call(cBind, ...)是缓慢或大数据失败.所以这是一个更复杂但更快更有效的方法:

n <- nrow(df)
nlevels <- sapply(df, nlevels)
i <- rep(seq_len(n), ncol(df))
j <- unlist(lapply(df, as.integer)) +
     rep(cumsum(c(0, head(nlevels, -1))), each = n)
x <- 1
sparseMatrix(i = i, j = j, x = x)
Run Code Online (Sandbox Code Playgroud)


Ben*_*ker 6

使用 可以更紧凑地完成此操作Matrix:::sparse.model.matrix,尽管要求所有变量都具有所有列会使事情变得更加困难。

生成输入:

set.seed(123)
n <- 6
df <- data.frame(x = sample(c("A", "B", "C"), n, TRUE),
                 y = sample(c("D", "E"),      n, TRUE))
Run Code Online (Sandbox Code Playgroud)

如果您不需要所有变量的所有列,您可以这样做:

library(Matrix)
sparse.model.matrix(~.-1,data=df)
Run Code Online (Sandbox Code Playgroud)

如果您需要所有列:

fList <- lapply(names(df),reformulate,intercept=FALSE)
mList <- lapply(fList,sparse.model.matrix,data=df)
do.call(cBind,mList)
Run Code Online (Sandbox Code Playgroud)