Reputation: 6806
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
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
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