5

I want to create several columns with a ifelse()-condition. Here is my example-code:

df <- tibble( 
date = lubridate::today() +0:9,
return= c(1,2.5,2,3,5,6.5,1,9,3,2))

And now I want to add new columns with ascending conditions (from 1 to 8). The first column should only contain values from the "return"-column, which are higher than 1, the second column should only contain values, which are higher than 2, and so on...

I can calculate each column with a mutate() function:

df <- df %>% mutate( `return>1`= ifelse(return > 1, return, NA))
df <- df %>% mutate( `return>2`= ifelse(return > 2, return, NA))
df <- df %>% mutate( `return>3`= ifelse(return > 3, return, NA))
df <- df %>% mutate( `return>4`= ifelse(return > 4, return, NA))
df <- df %>% mutate( `return>5`= ifelse(return > 5, return, NA))
df <- df %>% mutate( `return>6`= ifelse(return > 6, return, NA))
df <- df %>% mutate( `return>7`= ifelse(return > 7, return, NA))
df <- df %>% mutate( `return>8`= ifelse(return > 8, return, NA))


> head(df)
# A tibble: 6 x 10
date       return `return>1` `return>2` `return>3` `return>4` `return>5` `return>6` `return>7` `return>8`
<date>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>
1 2019-03-08    1         NA         NA         NA         NA         NA         NA           NA         NA
2 2019-03-09    2.5        2.5        2.5       NA         NA         NA         NA           NA         NA
3 2019-03-10    2          2         NA         NA         NA         NA         NA           NA         NA
4 2019-03-11    3          3          3         NA         NA         NA         NA           NA         NA
5 2019-03-12    5          5          5          5          5         NA         NA           NA         NA
6 2019-03-13    6.5        6.5        6.5        6.5        6.5        6.5        6.5         NA         NA

Is there an easier way to create all these columns and reduce all this code? Maybe with a map_function? And is there a way to automatically name the new columns?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
TobKel
  • 1,293
  • 8
  • 20

3 Answers3

6

An option with lapply

n <- seq(1, 8)
df[paste0("return > ", n)] <- lapply(n, function(x) 
                    replace(df$return, df$return <= x, NA))


#       date       return `return > 1` `return > 2` `return > 3` .....
#  <date>      <dbl>        <dbl>        <dbl>        <dbl> 
#1 2019-03-08    1           NA           NA           NA  
#2 2019-03-09    2.5          2.5          2.5         NA    
#3 2019-03-10    2            2           NA           NA    
#4 2019-03-11    3            3            3           NA    
#5 2019-03-12    5            5            5            5    
#6 2019-03-13    6.5          6.5          6.5          6.5  
#...
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • And is there a way to add decimal pionts? For example: return>1 ; return>1.5 ; return>2 ; return>2.5 – TobKel Mar 08 '19 at 09:15
  • 2
    @T.Kel Updated the answer for that. Now for decimals you can change `n` to `n <- seq(1, 8, 0.5)` and it will work. – Ronak Shah Mar 08 '19 at 09:21
  • `Warning messages: 1: In 1:n : numerical expression has 7 elements: only the first used 2: In 1:n : numerical expression has 7 elements: only the first used` – TobKel Mar 08 '19 at 09:23
  • Check the answer again. I Changed `1:n` to only `n` since now `n` holds the sequence we don't need to do `1:n`. – Ronak Shah Mar 08 '19 at 09:24
3

Here is a for loop solution:

for(i in 1:8){
  varname =paste0("return>",i)
  df[[varname]] <- with(df, ifelse(return > i, return, NA))
}
LocoGris
  • 4,432
  • 3
  • 15
  • 30
3

use purrr::map_df

> bind_cols(df,purrr::map_df(setNames(1:8,paste0('return>',1:8)),
+               function(x) ifelse(df$return > x, df$return, NA)))
# A tibble: 6 x 10
#   date       return `return>1` `return>2` `return>3` `return>4` `return>5` `return>6` `return>7` `return>8`
#   <date>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl>
# 1 2019-03-08    1         NA         NA         NA         NA         NA         NA           NA         NA
# 2 2019-03-09    2.5        2.5        2.5       NA         NA         NA         NA           NA         NA
# 3 2019-03-10    2          2         NA         NA         NA         NA         NA           NA         NA
# 4 2019-03-11    3          3          3         NA         NA         NA         NA           NA         NA
# 5 2019-03-12    5          5          5          5          5         NA         NA           NA         NA
# 6 2019-03-13    6.5        6.5        6.5        6.5        6.5        6.5        6.5         NA         NA
quan
  • 68
  • 5