Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply function on each cell in a column and add the result to a new column

Tags:

r

data.table

I have a data.table as shown below. What I want is to apply a function to each of the elements in column C. The function will take in a vector(since Col C contains vector elements) and return another vector. This resultant vector should be added to a new column.

     A   B         C        
1:  16  151 c(2579, 2659, 2752)
2:  16  152 c(2580, 2660, 2753) 
3:  16  153 c(2581, 2661, 2754)
4:  16  154 c(2582, 2662, 2755)
5:  16  155 c(2583, 2663, 2756)
6:  16  156 c(2584, 2664, 2757)

For example let us consider a function 'isOdd' that takes in a vector and returns a logical vector. The output table after applying this function should look like

     A   B           C            isOdd
1:  16  151 c(2579, 2659, 2752)  c(T,T,F)
2:  16  152 c(2580, 2660, 2753)  c(F,F,T) 
3:  16  153 c(2581, 2661, 2754)  c(T,T,F)
4:  16  154 c(2582, 2662, 2755)  c(F,F,T)
5:  16  155 c(2583, 2663, 2756)  c(T,T,F)
6:  16  156 c(2584, 2664, 2757)  c(F,F,T)

How do I achieve this?

like image 905
Anirudh Jayakumar Avatar asked May 03 '13 08:05

Anirudh Jayakumar


2 Answers

Using R's apply functions, we can easily accomplish your goal. Lets say that d is your data.table you are working with. Basically lapply passes each row of column "C" to the anonymous function, which then further passes each element of the passed in row to the function, isOdd.

isOdd <- function(x) {
    if (x %% 2 == 0) return("F") 
    else return("T")
}

d$isOdd <- lapply(d$C, function(x) sapply(x, isOdd))
like image 183
Chris Kelly Avatar answered Nov 04 '22 15:11

Chris Kelly


DT = data.table(A=letters[1:3], B=list(1:3,4:6,7:8))
DT
   A     B   # notice B is list column containing vectors of different lengths
1: a 1,2,3   # it isn't a character vector, although it prints like one
2: b 4,5,6
3: c   7,8

> DT[,L:=sapply(B,length)][]
   A     B L
1: a 1,2,3 3
2: b 4,5,6 3
3: c   7,8 2

> isOdd = function (x) x%%2 == 0

> DT[,odd:=lapply(B,isOdd)][]
   A     B L              odd
1: a 1,2,3 3 FALSE,TRUE,FALSE
2: b 4,5,6 3  TRUE,FALSE,TRUE
3: c   7,8 2       FALSE,TRUE 
like image 22
Matt Dowle Avatar answered Nov 04 '22 14:11

Matt Dowle