1

I am trying to write some R code which will take the iris dataset and do a log transform of the numeric columns as per some criterion, say if skewness > 0.2. I have tried to use ldply, but it doesn't quite give me the output I want. It is giving me a transposed data frame, the variable names are missing and the non-numeric column entries are messed up.

Before posting this question I searched and found the following related topics but didn't quite meet what exactly I was looking for

Selecting only numeric columns from a data frame

extract only numeric columns from data frame data

Below is the code. Appreciate the help!

data(iris)
df <- iris
df <- ldply(names(df), function(x)
  { 
  if (class(df[[x]])=="numeric") 
    {
    tmp <- df[[x]][!is.na(df[[x]])]
    if (abs(skewness(tmp)) > 0.2) 
      {
       df[[x]] <- log10( 1 + df[[x]]  )
      }
    else df[[x]] <- df[[x]]
  }
  else df[[x]] <- df[[x]]
  #df[[x]] <- data.frame(df[[x]])
  #df2 <- cbind(df2, df[[x]])
  #return(NULL)
   }
  )
Cœur
  • 37,241
  • 25
  • 195
  • 267
Vaidy
  • 11
  • 2
  • You may not need `ldply`, use `lapply` and other base R options. From which package, you got the `skewness`? – akrun Aug 08 '16 at 08:15

2 Answers2

0

Try with lapply:

#Skewness package
library(e1071)

lapply(iris, function(x) {
        if(is.numeric(x)){ 
            if(abs(skewness(x, na.rm = T))>0.2){
            log10(1 + x)} else x
            }
    else x
    })
thepule
  • 1,721
  • 1
  • 12
  • 22
  • Thank you. I thought that lapply takes only lists as input, looks like it can take a data frame too. Maybe it coerces it to a list? – Vaidy Aug 09 '16 at 12:48
0

We can use lapply

library(e1071)
lapply(iris, function(x) if(is.numeric(x) & abs(skewness(x, na.rm = TRUE)) > 0.2) 
                      log10(1+x) else x)

We can also loop by the columns of interest after creating a logical index

i1 <- sapply(iris, is.numeric)
i2 <- sapply(iris[i1], function(x) abs(skewness(x, na.rm = TRUE)) > 0.2)
iris[i1][i2] <- lapply(iris[i1][i2], function(x) log10(1+x))
akrun
  • 874,273
  • 37
  • 540
  • 662