Search code examples
rdataframesapply

Replace elements of a data frame with special columns (list columns) depending on a threshold value


I have a data frame df with special columns:

df<- data.frame(w= 1:3, x=3:5, y=6:8, z = I(list(1:2, 1:3, 1:4)))
df <- as.data.frame(do.call(cbind, lapply(df[1:3], function(x) Map("*", 
         df$z, x))))

>df

           w                x                  y
        1, 2             3, 6              6, 12
     2, 4, 6         4, 8, 12          7, 14, 21
 3, 6, 9, 12    5, 10, 15, 20      8, 16, 24, 32

I want to replace any number in df which has a value less than 6 with the number 6 and every value greater than 8 with the number 8. I do not want to touch the numbers in between and I want to maintain the data frame structure.

To achieve this, I have written a function transfo

transfo<- function(x){
  x <- unlist(x)
  if (x < 6){ x <- 6}
  if (x > 8){ x <- 8}
  x 
}

When I run the following code:

transformed <- as.data.frame(sapply(df, transfo))

I get 10 of the warning messages:

1: In if (x < 6) { :
  the condition has length > 1 and only the first element will be used

...and I do not get the required output.

My expected output is

>transformed 

               w                x                  y
            6, 6             6, 6               6, 8
         6, 6, 6          6, 8, 8            7, 8, 8
      6, 6, 8, 8       6, 8, 8, 8         8, 8, 8, 8

I will be very grateful for a hint on the fastest way to replace all elements of the data frame df with 6 if they are less than 6 and with 8 if they are greater than 8 since I work with a large data set with 3000 rows.

Thanks in advance.


Solution

  • Also works

    > out <- as.data.frame(do.call(cbind, lapply(df, function(i){
         lapply(i, function(j){
             ifelse((j < 6), 6, ifelse((j > 8), 8, j))
         })
     })))
    > out
               w          x          y
    1       6, 6       6, 6       6, 8
    2    6, 6, 6    6, 8, 8    7, 8, 8
    3 6, 6, 8, 8 6, 8, 8, 8 8, 8, 8, 8