首页 > 解决方案 > 带有 for 循环语法的 R 函数

问题描述

我在 R 中创建了一个 for 循环,它mention.parkinsons根据列表中包含的变量的值设置变量的值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,))
}

这很好用,但我想创建一个函数,以便可以使用其他变量复制此任务。我的尝试是:

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,))
  }

我尝试执行nap_analyse <- forloop_nap(nap_analyse, mention.parkinsons, mention.parkinsons.tags它将执行原始 for 循环,但这不起作用。我认为我的语法有问题。编写函数的正确方法是forloop_nap()什么?


可重现的例子:

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,))
}

原始数据框:

> 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

预期结果(与 for 循环一起使用,但希望将其编写为函数,以便可以在其他情况下重现它)

      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

标签: rfunctionfor-loopdplyr

解决方案


您在这里不需要循环:

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

推荐阅读