多列动态指定上的“ if_else”条件

问题描述

我正在基于多个现有列的值尝试mutate的新列,以便如果任何列等于指定值,则if_else的值为TRUE。我可以使用if_else中的多个比较表达式来执行此操作,但是这不起作用,因为我需要使用准引号动态指定列。重新解释下面的解释性注释。

对于如何评估多个动态指定列的比较的建议,我将不胜感激。

预先感谢您的帮助!

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter,lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect,setdiff,setequal,union

mtcars <- head(mtcars,8)

# Desired output,using individual comparisons for each column
mtcars %>% 
  mutate(color = if_else(
    (gear == 4 | carb == 4),"purple","green")
  )
#>    mpg cyl  disp  hp drat    wt  qsec vs am gear carb  color
#> 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 purple
#> 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 purple
#> 3 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 purple
#> 4 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1  green
#> 5 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2  green
#> 6 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1  green
#> 7 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 purple
#> 8 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 purple

# Failed attempts to do comparisons on multiple columns
mtcars %>% 
  mutate(color = if_else(
    (gear|carb == 4),"green")
  )
#>    mpg cyl  disp  hp drat    wt  qsec vs am gear carb  color
#> 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 purple
#> 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 purple
#> 3 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 purple
#> 4 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 purple
#> 5 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 purple
#> 6 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 purple
#> 7 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 purple
#> 8 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 purple

mtcars %>% 
  mutate(color = if_else(
    (c(gear,carb) == 4),"green")
  )
#> Error: Problem with `mutate()` input `color`.
#> x Input `color` can't be recycled to size 8.
#> ℹ Input `color` is `if_else((c(gear,"green")`.
#> ℹ Input `color` must be size 8 or 1,not 16.

# Using dynamically specified columns and quasiquotation
my_vars <- c("gear","carb")

# Quasiquotation works with `select`,and `coalesce`
mtcars %>% select(!!!syms(my_vars))
#>                   gear carb
#> Mazda RX4            4    4
#> Mazda RX4 Wag        4    4
#> Datsun 710           4    1
#> Hornet 4 Drive       3    1
#> Hornet Sportabout    3    2
#> Valiant              3    1
#> Duster 360           3    4
#> Merc 240D            4    2
mtcars %>% mutate(any_value = coalesce(!!!syms(my_vars)))
#>    mpg cyl  disp  hp drat    wt  qsec vs am gear carb any_value
#> 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4         4
#> 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4         4
#> 3 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1         4
#> 4 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1         3
#> 5 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2         3
#> 6 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1         3
#> 7 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4         3
#> 8 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2         4

# Desired `mutate`: if any columns (via quasiquotation) == 4,then TRUE
mtcars %>% 
  mutate(color = if_else(
    any(!!!syms(my_vars) == 4),"green")
  )
#> Error in splice(dot_call(capture_dots,frame_env = frame_env,named = named,: 'list' object cannot be coerced to type 'double'

reprex package(v0.3.0)于2020-08-17创建

解决方法

mtcars %>%
  mutate(
    flag = eval(parse(text = str_c(my_vars," == 4",collapse = "|"))),color = if_else(flag,"purple","green")
  ) %>%
  select(-flag)
,

您可以对要检查的列进行子集化,将它们与值进行比较,然后执行rowSums来计算它们的出现并根据该值分配值。

mtcars$any_value <- ifelse(rowSums(mtcars[my_vars] == 4) > 0,'purple','green')

#Without ifelse
mtcars$any_value <- c('green','purple')[(rowSums(mtcars[my_vars] == 4) > 0) + 1]

mtcars
#                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb any_value
#Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4    purple
#Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4    purple
#Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1    purple
#Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1     green
#Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2     green
#Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1     green
#Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4    purple
#Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2    purple

使用tidyverserowwise的{​​{1}}方法

c_across

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...