0

I ended up with a big data.table and I want to apply a function per row. It works with data.frame and apply, but I want to get a solution with data.table.

>sdata
Z_2016_11      Z_2016_10        Z_2016_09        Z_2016_08       Z_2016_07
 1:  21          32               15               NA              NA     
 2:  6           17               NA               NA              NA         
 3:  2           7                9                230             NA           
 4:  5           19               28               30              0          
 5:  16          29               30               105             0           
 6:  2           0                0                0               NA  

I want to order it as following

>sdata
Z_1              Z_2              Z_3              Z_4             Z_5
 1:  15          32               21               NA              NA     
 2:  17          6                NA               NA              NA         
 3:  230         9                7                2               NA           
 4:  0           30               28               19              5          
 5:  0          105               30               29             16           
 6:  0           0                0                2               NA  

With a data.frame I can use

t(apply(sdata[, grep("Z", names(sdata), value = TRUE),with=FALSE],1,
           function(tmp) c(rev(tmp[!is.na(tmp)]), 
           rep(NA, times = length(tmp) - length(tmp[!is.na(tmp)])))))

I tried it the following way

trimt <- function(tmp){

  c(rev(tmp[!is.na(tmp)]), rep(NA, times = length(tmp) - length(tmp[!is.na(tmp)])))

}    

sdata[,trimt(get(grep("Z", names(sdata), value = TRUE))),by=1:nrow(sdata)]

So I can order it easily, but only a vector returns. Is it possible to use a data.table similar to apply and return a new matrix?

Frank
  • 66,179
  • 8
  • 96
  • 180
Frank123
  • 3
  • 4
  • For the first row, why do you have 15 32 21, the order is not right' – akrun Jan 04 '17 at 13:13
  • I want to remove the NAs, then reverse the rest of the row and add NAs for the missing values and replace the row. – Frank123 Jan 04 '17 at 13:23
  • Posted a solution based on data.table – akrun Jan 04 '17 at 13:25
  • Generally, best to also describe what your function is meant to do, not simply to show it. Your `apply` code is complicated enough that it's not obvious to me what it's doing, anyway. – Frank Jan 04 '17 at 14:57

1 Answers1

2

We can use data.table methods

setnames(sdata[,  {un1 <- unlist(.SD)
       as.list(`length<-`(rev(un1[!is.na(un1)]), length(un1))) 
    } , by = .(grp=1:nrow(sdata))][, grp := NULL], paste0("Z", 1:5))[]
#    Z1  Z2 Z3 Z4 Z5
#1:  15  32 21 NA NA
#2:  17   6 NA NA NA
#3: 230   9  7  2 NA
#4:   0  30 28 19  5
#5:   0 105 30 29 16
#6:   0   0  0  2 NA
akrun
  • 874,273
  • 37
  • 540
  • 662