在 r 中创建一个稀疏矩阵,每行具有一定数量的整数值

Creating a sparse matrix in r with a set number of integer values per row

我正在尝试创建一个稀疏矩阵,其中每一行最多有 n 个条目,每个条目都是一定范围内的整数,然后我可以将其用作社交网络分析的邻接矩阵。例如,一个 80X80 矩阵,其中每行有 10 个或更少的条目,这些条目是 1-4 之间的整数。目标是表示您将从社交网络调查中获得的数据类型,其中受访者选择 1 到 4 之间的值来表示他们与调查中最多 possibilities/columns 中的 10 个人的关系。

我可以使用 "rsparsematrix" 函数创建一个稀疏矩阵,使用密度命令可以估计所需的响应数量,但我无法控制每行的响应数量,因此必须这样做将随机值转换为我所需范围内的整数的额外处理。

例如:我可以从类似

的内容开始
M1<-rsparsematrix(80, 80, density = .1, symmetric = FALSE)

一种更有前途的方法(来自 https://www.r-bloggers.com/casting-a-wide-and-sparse-matrix-in-r/)是生成值,然后使用 "transform" 将它们转换为矩阵。这允许我控制整数值,但仍然没有得到每行有限数量的响应。

博客中的示例代码如下:

set.seed(11)

 N = 10
data = data.frame(
row = sample(1:3, N, replace = TRUE),
col = sample(LETTERS, N, replace = TRUE),
value = sample(1:3, N, replace = TRUE))

data = transform(data,
              row = factor(row),
              col = factor(col))  "

这可以调整为提供所需的 80x80 矩阵,但不能解决限制每行响应的问题,并且在相同 row/column 组合中出现重复条目​​的情况下,将导致输出范围值,因为它通过求和来解决重复条目。

如有任何建议,我们将不胜感激。

作为奖励问题,您将如何创建随机的空响应行?例如,在 80*80 矩阵中,您如何引入 40 个没有值的随机行?如上文所述,这对应于缺失的调查数据。

下面的代码将执行您想要的操作。它会生成您的随机稀疏矩阵,将其四舍五入为整数,然后对于超过 10 个条目的每一行,随机生成一些条目 NA 直到只剩下 10 个。然后它使所有非 NA 条目成为 1 到 4 之间的随机数。

 library(Matrix)
M1<-as.data.frame(as.matrix((rsparsematrix(80, 80, density = .1, symmetric = FALSE))))
M1 <- as.data.frame(apply(M1,1,round))
M1<-as.data.frame(sapply(M1,function(x) ifelse(x==0,NA,x)))
rows<-which(apply(M1,1,function(x) sum(!(is.na(x)))) >10)

for(i in rows)
{
toNA<-setdiff(which(!(is.na(M1[i,]))),sample(which(!(is.na(M1[i,]))),10,replace=F))
M1[i,toNA] <- NA  
)

for(i in 1:nrow(M1))
{
M1[i,which(!(is.na(M1[i,])))] <- sample(1:4,length(M1[i,which(! 
(is.na(M1[i,])))]),replace=T) 
}

您可以尝试使用行 (i)、列 (j) 和值 (x) 组件构建备用矩阵。这涉及根据您的行和值约束进行抽样。

# constraints
values <- 1:4
maxValuesPerRow <- 10
nrow <- 80
ncol <- 80

# sample values : how many values should each row get but <= 10 values
set.seed(1)
nValuesForEachRow <- sample(maxValuesPerRow, nrow, replace=TRUE)

# create matrix
library(Matrix)
i <- rep(seq_len(nrow), nValuesForEachRow)                       # row
j <- unlist(lapply(nValuesForEachRow, sample, x=seq_len(ncol)))  # which columns
x <- sample(values, sum(nValuesForEachRow), replace=TRUE)        # values
sm <- sparseMatrix(i=i, j=j, x=x)

检查

dim(sm)
table(rowSums(sm>0))
table(as.vector(sm))

注意,不能像下面这样对列进行采样,因为这可能会给出重复值,因此使用了循环。

j <- sample(seq_len(ncol), sum(nValuesForEachRow), replace=TRUE)