user2543622
user2543622

Reputation: 6806

R data manipulation matrix

I have a column as below. Only for non-null elements, I want to get a matrix such as below. 6th column represent the actual value.

1 0 0 0 0 1

0 1 0 0 0 2

0 0 0 1 0 5

Any hint what is the efficient way to do this? which commands should I use? I am thinking of writing a if loop within for loop, but don't think it will be very efficient :(

abc=c('1','2','null','5','null')

Upvotes: 0

Views: 89

Answers (2)

thelatemail
thelatemail

Reputation: 93938

Assuming there is an error in your example, this is just a dummy variable coding essentially:

abc <- c('1','2','null','5','null')
abc <- factor(abc,levels=1:5)
cbind(model.matrix(~abc+0),orig=na.omit(abc))

#  abc1 abc2 abc3 abc4 abc5 orig
#1    1    0    0    0    0    1
#2    0    1    0    0    0    2
#4    0    0    0    0    1    5

If you want to automatically calculate the range of possible factors, try:

abc <- c('1','2','null','5','null')
rng <- range(as.numeric(abc),na.rm=TRUE)
abc <- factor(abc,levels=seq(rng[1],rng[2]))
cbind(model.matrix(~abc+0),orig=na.omit(abc))

#  abc1 abc2 abc3 abc4 abc5 orig
#1    1    0    0    0    0    1
#2    0    1    0    0    0    2
#4    0    0    0    0    1    5

Upvotes: 1

IRTFM
IRTFM

Reputation: 263481

It's not clear why that matrix is six elements wide but if it is length(abc)+1 then just substitute that expression for my use of 6.

> abcn <- as.numeric(abc)
> zero <- matrix(0,nrow=length(abcn[!is.na(abcn)]), ncol=6)
> zero[ cbind(1:3, which( !is.na(abcn)) ) ] <- 1
> zero[ , 6] <- abcn[!is.na(abcn)]
> zero
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    0    0    0    0    1
[2,]    0    1    0    0    0    2
[3,]    0    0    0    1    0    5

You can index teh [<- function for matrices with a two coulmn matrix and that's what I'm doing in the third line. The rest of it is ordinary matrix indexing.

Upvotes: 1

Related Questions