R function with for loop syntax

Viewed 48

I have made a for loop in R which sets the value of the variable mention.parkinsons based on the value of the variables contained in the list mention.parkinsons.tags:

for(i in mention.parkinsons.tags){
  nap_analyse <- nap_analyse %>%
    mutate(mention.parkinsons = case_when(
      mention.parkinsons == TRUE & nap_analyse[i] == TRUE ~ TRUE,
      mention.parkinsons == TRUE & nap_analyse[i] == FALSE ~ TRUE,
      mention.parkinsons == FALSE & nap_analyse[i] == TRUE ~ TRUE,
      mention.parkinsons == FALSE & nap_analyse[i] == FALSE ~ FALSE,))
}

This works well but I would like to create a function so I can replicate this task with other variables. My attempt was:

forloop_nap <- function(dataframe, new_var, tags_list) {
  for(i in tags_list){
    dataframe <- dataframe %>%
      mutate({{new_var}} := case_when(
        {{new_var}} == TRUE & {{dataframe}}[i] == TRUE ~ TRUE,
        {{new_var}} == TRUE & {{dataframe}}[i] == FALSE ~ TRUE,
        {{new_var}} == FALSE & {{dataframe}}[i] == TRUE ~ TRUE,
        {{new_var}} == FALSE & {{dataframe}}[i] == FALSE ~ FALSE,))
  }

I tried executing nap_analyse <- forloop_nap(nap_analyse, mention.parkinsons, mention.parkinsons.tags which would execute the original for loop but this won't work. I assume there is a problem with my syntax which. What would be the correct way to write the function forloop_nap()?


Reproducible example:

library(wakefield)

dataframe <- data.frame(
  v1 = r_sample_logical(10, prob = NULL, name = "Logical" ),
  v2 = r_sample_logical(10, prob = NULL, name = "Logical" )
)

mention.var.tag <- list(
  "v1",
  "v2")

dataframe <- add_column(dataframe, mention.parkinsons = FALSE)

for(i in mention.var.tag){
  dataframe <- dataframe %>%
    mutate(mention.parkinsons = case_when(
      mention.parkinsons == TRUE & dataframe[i] == TRUE ~ TRUE,
      mention.parkinsons == TRUE & dataframe[i] == FALSE ~ TRUE,
      mention.parkinsons == FALSE & dataframe[i] == TRUE ~ TRUE,
      mention.parkinsons == FALSE & dataframe[i] == FALSE ~ FALSE,))
}

Original dataframe:

> dataframe
      v1    v2
1  FALSE FALSE
2   TRUE FALSE
3   TRUE  TRUE
4   TRUE FALSE
5   TRUE FALSE
6  FALSE  TRUE
7   TRUE FALSE
8  FALSE FALSE
9   TRUE FALSE
10  TRUE  TRUE

Expected result (works with for loop but looking to write it as a function so it can be reproduced for other situations)

      v1    v2 mention.parkinsons
1  FALSE FALSE              FALSE
2   TRUE FALSE               TRUE
3   TRUE  TRUE               TRUE
4   TRUE FALSE               TRUE
5   TRUE FALSE               TRUE
6  FALSE  TRUE               TRUE
7   TRUE FALSE               TRUE
8  FALSE FALSE              FALSE
9   TRUE FALSE               TRUE
10  TRUE  TRUE               TRUE
2 Answers

You don't need a loop here :

library(dplyr)

mention.var.tag <- c("v1","v2")

forloop_nap <- function(dataframe, new_var, tags_list) {
  dataframe %>%
    mutate({{new_var}} := do.call(`|`, dataframe[tags_list]))
    #Also another way with rowSums 
    #mutate({{new_var}} := rowSums(dataframe[tags_list]) > 0)
}

dataframe <- forloop_nap(dataframe, mention.parkinsons, mention.var.tag)
dataframe

#      v1    v2 mention.parkinsons
#1  FALSE FALSE              FALSE
#2   TRUE FALSE               TRUE
#3  FALSE  TRUE               TRUE
#4  FALSE  TRUE               TRUE
#5   TRUE  TRUE               TRUE
#6   TRUE FALSE               TRUE
#7  FALSE FALSE              FALSE
#8   TRUE FALSE               TRUE
#9   TRUE FALSE               TRUE
#10 FALSE FALSE              FALSE
dataframe$mention.parkinsons <- ifelse(dataframe$v1 + dataframe$v2 > 0, TRUE, FALSE)
Related