简而言之:您能否在mutate中使用!!!拼接和case_when的列表输入,以及如何使用?
正如在对previous question的回答中所提到的,从dplyr >0.7.0开始,您可以在mutate()的case_when()中使用纯变量名
接下来,在case_when的help file中,它展示了如何像这样使用模式和!!!的列表:(模式是错误的,首先是大小写,但这是实际文档中的情况,与我的问题无关)
x <- 1:50
patterns <- list(
TRUE ~ as.character(x),
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
x %% 35 == 0 ~ "fizz buzz"
)
case_when(!!! patterns)然而,将这些方法结合起来似乎行不通:
testframe <- tibble(y = 1:50) #Switching to y so the x from earlier can't interfere
testframe2 <- testframe %>%
mutate(
fizzbuzz = case_when(
y %% 35 == 0 ~ "fizz buzz",
y %% 5 == 0 ~ "fizz",
y %% 7 == 0 ~ "buzz",
TRUE ~ as.character(y)
)
)
patterns <- list(
y %% 35 == 0 ~ "fizz buzz",
y %% 5 == 0 ~ "fizz",
y %% 7 == 0 ~ "buzz",
TRUE ~ as.character(y)
)
testframe3 <- testframe %>%
mutate(
fizzbuzz = case_when(
!!!(patterns)
)
)testframe2将正常工作,而testframe3给出以下错误:
Error in mutate_impl(.data, dots) :
Evaluation error: object 'y' not found.我假设这里有一些NSE的魔力在起作用,但我还没有设法通过quo()来摆脱这个问题。我确实研究了testframe2和3的quo()(programming with dplyr vignette中建议的一种调试方法)。我注意到它们是一样的:
testframe2quo <- quo(testframe %>%
mutate(
fizzbuzz = case_when(
y %% 35 == 0 ~ "fizz buzz",
y %% 5 == 0 ~ "fizz",
y %% 7 == 0 ~ "buzz",
TRUE ~ as.character(y)
)
)
)
testframe3quo <- quo(testframe %>%
mutate(
fizzbuzz = case_when(
!!!(patterns)
)
)
)
testframe2quo
<quosure: global>
~testframe %>% mutate(fizzbuzz = case_when(y%%35 == 0 ~ "fizz buzz",
y%%5 == 0 ~ "fizz", y%%7 == 0 ~ "buzz", TRUE ~ as.character(y)))
testframe3quo
<quosure: global>
~testframe %>% mutate(fizzbuzz = case_when(y%%35 == 0 ~ "fizz buzz",
y%%5 == 0 ~ "fizz", y%%7 == 0 ~ "buzz", TRUE ~ as.character(y)))所有这些都让我回到了我的问题上:可以在mutate中使用!!!拼接和case_when的列表输入吗?如何使用?
发布于 2018-02-22 19:49:37
您应该将案例包装在exprs中,而不是list中,并使用前缀.data
patterns <- rlang::exprs(
.data$y %% 35 == 0 ~ "fizz buzz",
.data$y %% 5 == 0 ~ "fizz",
.data$y %% 7 == 0 ~ "buzz",
TRUE ~ as.character(.data$y)
)
mutate(testframe, fizzbuzz = case_when(!!! patterns))https://stackoverflow.com/questions/48925980
复制相似问题