2015-05-13 24 views
5

mam tę listę ciągów:lista konwersji indeksów macierzy rzadkich do matrycy w R

dat <- list(V1=c("1:23","4:12"),V2=c("1:3","2:12","6:3")) 

elementy lista V1 i V2 oznaczają kolumny. 1:23 oznacza "pierwszy wpis w tej kolumnie ma wartość 23". Wszystkie inne wpisy powinny wynosić zero. wymiar macierzy wskazuje najwyższej pozycji, w tym przypadku mamy 2 kolumn (V1 oraz V2) i najwyżej numer rzędu wynosi 6, tak by spowodować macierzy 2x6 jak poniżej:

matrix(c(23,3, 
    0,12, 
    0,0, 
    12,0, 
    0,0, 
    0,3),nrow=6,ncol=2,byrow=T) 

Jak można osiągnąć tę zmianę?

+0

Czy chodziło Ci napisać 'matrycowy (C (23,3' –

+0

"Wszystkie pozostałe wpisy są zerowe" jest fałszywe, lub w najlepszym razie mylące ... – Frank

+0

@EricBrooks dzięki, poprawiony – spore234

Odpowiedz

4

Możesz także spróbować

library(dplyr) 
library(tidyr) 
library(Matrix) 

d1 <- unnest(dat,col) %>% 
      separate(x, into=c('row', 'val'), ':', convert=TRUE) %>% 
      extract(col, into='col', '\\D+(\\d+)', convert=TRUE) 

as.matrix(with(d1, sparseMatrix(row, col, x=val))) 
#  [,1] [,2] 
#[1,] 23 3 
#[2,] 0 12 
#[3,] 0 0 
#[4,] 12 0 
#[5,] 0 0 
#[6,] 0 3 
+0

'unnest (setNames (dat, seq_along (dat)), col)' jest bardzo podobny do 'stack (dat)'. 'as.numeric' działa tak jak dobrze na 'ind' w drugim, tak jak na' col' w poprzednim – Frank

+0

@Frank Najpierw użyłem 'stosu' (w edit), ale potem pomyślałem, że ludzie lubią 'unnest' ponad' stack', a także używają funkcji głównie z 'tidyr/dplyr' czyni go bardziej atrakcyjnym :-) – akrun

+1

Lub, faktycznie,' unnest (dat, col) ', aby go zachować w tidyr/dplyr :) Nie trzeba zmieniać nazwy – Frank

3

Rozwiązanie:

dat <- list(V1=c("1:23","4:12"),V2=c("1:3","2:12","6:3")) 
y <- inverse.rle(list(values = 1:length(dat),lengths = sapply(dat,length))) 

x <- as.numeric(unlist(sapply(dat,function(y)sapply(strsplit(y,":"),function(x)x[1])))) 
val <- as.numeric(unlist(sapply(dat,function(y)sapply(strsplit(y,":"),function(x)x[2])))) 

num_row <- max(x) 
num_col <- max(y) 
m = matrix(0, nrow = num_row, ncol = num_col) 
m[cbind(x,y)] <- val 
m