Создание разреженной матрицы в r с заданным числом целочисленных значений в строке - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь создать разреженную матрицу, в которой для каждой строки есть максимум n записей, каждый из которых является целым числом в определенном диапазоне, который я мог бы затем использовать в качестве матрицы смежности для анализа социальной сети.Например, матрица 80X80, где каждая строка имеет 10 или меньше записей, которые являются целыми числами от 1-4.Цель состоит в том, чтобы представить данные, которые вы получили бы из опроса в социальных сетях, в котором респонденты выбирали значения от 1 до 4, чтобы указать свою связь с 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, но не решает проблему ограничения ответов на строку и, в случае дублирования записей в одной и той же комбинации строки / столбца, приведет к выходу за пределы диапазона значений, поскольку он разрешает повторяющиеся записи путем взятия суммы.

Буду признателен за любые предложения.

В качестве дополнительного вопроса, как бы вы тогда создали случайные строки с нулевыми ответами?Например, в матрице 80 * 80, как вы можете ввести 40 случайных строк без значений?Как и в приведенном выше описании, это будет соответствовать отсутствующим данным опроса.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Вы можете попытаться построить запасную матрицу, используя компоненты строки (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)

check

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

примечание, не могу просто сэмплировать столбцы, как показано ниже, так как это может дать повторяющиеся значения, следовательно, цикл используется.

j <- sample(seq_len(ncol), sum(nValuesForEachRow), replace=TRUE) 
0 голосов
/ 15 февраля 2019

Код ниже будет делать то, что вы хотите.Он генерирует вашу случайную разреженную матрицу, округляет ее до целых чисел, а затем для каждой строки, содержащей более 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) 
}
...