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

时间:2019-02-15 00:58:27

标签: r random sparse-matrix adjacency-matrix

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

我可以使用“ rsparsematrix”函数创建一个稀疏矩阵,并且使用density命令可以估计所需的响应数,但是我无法控制每行的响应数,因此必须进行额外的处理才能转换随机值变成我想要的范围内的整数。

例如:我可以从

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

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

博客中的示例代码如下:

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矩阵,但不能解决限制每行响应的问题,并且如果同一行/列组合中的重复条目将导致值超出范围,因为它通过求和来解析重复的条目。

任何建议将不胜感激。

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

2 个答案:

答案 0 :(得分:0)

下面的代码将满足您的要求。它生成您的随机稀疏矩阵,将其四舍五入为整数,然后对于具有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) 
}

答案 1 :(得分:0)

您可以尝试使用行({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)