Search code examples
rfilterdatatabletransformationlogarithm

How can I convert a data table to its logarithm (+1, base 2) form in R while ignoring non-numeric values?


I'm trying to convert the values of a data table to its log(a)+1 (base 2) into a transformed data table in R. But the first two columns of the data tables are not numbers so I need to exclude them from the calculation or I will get an error. I do know how to do these two operations individually but when I combine them, I get an error saying the first two columns are not numerical values.

Here is my code:

logDT = log(DT, 2) + 1[, -c(1, 2)]

I am aware that I can just create an intermediary data table that excludes the columns first and then produce the log table, but I do need the first two columns in there in the log table so I'd rather just find a way to make my original code work.

Here's an example code (the only real difference between this and my actual code is that my actual code has two non-numerical columns while this code has one):

DT = data.table(x=c("b","b","b","a","a"),v=rnorm(5))

   x          v
1: b -0.4149946
2: b -0.3942900
3: b -0.0593134
4: a  1.1000254
5: a  0.7631757

Solution

  • Use which(sapply()) to get indices of numeric columns, then data.table::set() to transform:

    library(data.table)
    
    logDT <- DT
    
    for (j in which(sapply(logDT, is.numeric))) {
      set(logDT, j = j, value = log(logDT[[j]], 2) + 1)
    }
    
    logDT
    
       x        v1         v2
    1: b  0.148809 -0.2669889
    2: b       NaN  1.2980794
    3: b  1.827952 -1.0789923
    4: a -1.416422        NaN
    5: a  1.192227  1.1442347
    

    Example data:

    set.seed(13)
    
    DT <- data.table(x = c("b","b","b","a","a"), v1 = rnorm(5), v2 = rnorm(5))