-1

Currently , I have 4 lines for a simple ifelse on 4 columns. I'm pretty new in R, how can I do this in a single line ? Thank you ! :)

I tried to do that in function like

my_function <- function(var) {
datamart_apprentissage  <- mutate(datamart_apprentissage, var= ifelse(is.na(var), 0, 1))
}

my_function("VIE_OB3_1")
my_function("VIE_OB3_2")
my_function("VIE_OB3_3")
my_function("VIE_OB3_4")

but didnt work

datamart_apprentissage  <- mutate(datamart_apprentissage, VIE_OB3_1 = ifelse(is.na(VIE_OB3_1), 0, 1))
datamart_apprentissage  <- mutate(datamart_apprentissage, VIE_OB3_2 = ifelse(is.na(VIE_OB3_2), 0, 1))
datamart_apprentissage  <- mutate(datamart_apprentissage, VIE_OB3_3 = ifelse(is.na(VIE_OB3_3), 0, 1))
datamart_apprentissage  <- mutate(datamart_apprentissage, VIE_OB3_4 = ifelse(is.na(VIE_OB3_4), 0, 1))

Thank you !

  • 1
    Welcome to SO! Can you create a minimal [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) we can work with? – markus Jun 20 '19 at 07:50
  • 1
    Hello ! For general *loop* purposes, I would advise you to learn about `sapply()` and `lapply()` functions. You can get info about them by typing `help("sapply")` in the R terminal. Also, R supports more basic functions (`for()` and `while()`) – Elie Ker Arno Jun 20 '19 at 07:53

3 Answers3

1

You can use column-wise apply:

# Some data
df <- data.frame(a = c(1,2,NA,4), b = c(NA,NA,7,8))

# Function for replacing NA with value
myfun <- function(col) {
  out <- ifelse(is.na(col), 0, 1)
  return(out)
}

# Applying function column-wise (option = 2)
apply(df, 2, function(col) myfun(col))

# As oneliner
apply(df, 2, function(col) ifelse(is.na(col), 0, 1))
Esben Eickhardt
  • 3,183
  • 2
  • 35
  • 56
  • 1
    Or `df[, c("c", "e")] <- as.integer(!is.na(df[, c("c", "e")]))` – markus Jun 20 '19 at 07:59
  • Thanks for you answer, If I want do this to specifics colums like ```r df <- data.frame(a = c(1,2,NA,4), b = c(NA,NA,7,8)), d(NA,NA,7,8)),e(NA,NA,7,8)) ``` and I want apply only on c and e colums, how can I do this ? Thanks – Thibaut_MT Jun 20 '19 at 08:01
0

Here is a solution using dplyr, to customize which column are transformed use the .vars argument in mutate_at :

library("dplyr", quietly = TRUE, warn.conflicts = FALSE)
datamart_apprentissage <- matrix(sample(x = c(NA, 2:3), size = 5*4, replace = TRUE), ncol = 4)
datamart_apprentissage <- as_tibble(datamart_apprentissage )
#> Warning: `as_tibble.matrix()` requires a matrix with column names or a `.name_repair` argument. Using compatibility `.name_repair`.
#> This warning is displayed once per session.
names(datamart_apprentissage) <- paste0("VIE_OB3_", 1:4)

# --- What you wanna do
datamart_apprentissage %>% 
        mutate_at(.vars = paste0("VIE_OB3_", 1:4), .funs = function(x) ifelse(is.na(x), 0, 1))
#> # A tibble: 5 x 4
#>   VIE_OB3_1 VIE_OB3_2 VIE_OB3_3 VIE_OB3_4
#>       <dbl>     <dbl>     <dbl>     <dbl>
#> 1         0         1         1         1
#> 2         1         0         1         1
#> 3         1         1         0         0
#> 4         0         1         0         1
#> 5         1         1         0         1
cbo
  • 1,664
  • 1
  • 12
  • 27
0

You can use sapply which will keep the dataframe structure. Below is an exemple where you can replace the NA with "VALUE"

You can replace the function(x)ifelse by your own function (I have no experience with mutate so I can't help with that.

Also, you can select only specific rows/columns using [row,column]:

df <- data.frame(a=c(1,2,NA,NA,5),b=c(NA,7,8,NA,10),c=c(NA,7,8,NA,10),d=c(NA,7,8,NA,10),e=c(NA,7,8,NA,10))
df
df[,c(1,2)] <- sapply(df[,c(1,2)],function(x)ifelse(is.na(x),"VALUE",x))
df
Axel
  • 47
  • 7