[英]R dplyr using across() efficiently with mutate() and case_when()
Here is data:这是数据:
library(tidyverse)
set.seed(1234)
df1 <- tibble(
S1 = rnorm(5),
S2 = rnorm(5),
S3 = rnorm(5),
S4 = rnorm(5),
)
I want to apply an arithmetic transformation, truncate the distribution, and format values as integers.我想应用算术转换,截断分布,并将值格式化为整数。 This code works:
此代码有效:
df2 <- df1 %>%
mutate(across(everything(),
~
round(. * 10) + 50),
across(
everything(),
~
case_when(. < 45 ~ 45,
. > 55 ~ 55,
TRUE ~ .) %>%
as.integer(.)
))
But when I make the code more concise, placing all three operations within a single instance of across()
, as in:但是当我使代码更简洁时,将所有三个操作放在一个
across()
实例中,如下所示:
df3 <- df1 %>%
mutate(across(everything(),
~
round(. * 10) + 50) %>%
case_when(. < 45 ~ 45,
. > 55 ~ 55,
TRUE ~ .) %>%
as.integer(.)
)
I get this error:我收到此错误:
Error: Problem with `mutate()` input `..1`.
x Case 1 (`.`) must be a two-sided formula, not a `tbl_df/tbl/data.frame` object.
ℹ Input `..1` is ``%>%`(...)`.
Not sure what I'm doing wrong.不知道我做错了什么。 Thanks in advance for any help.
提前感谢您的帮助。
We can place them in a block {}
我们可以将它们放在一个块中
{}
df1 %>%
mutate(across(everything(), ~
(round(. * 10) + 50) %>%
{case_when(. < 45 ~ 45, . > 55 ~ 55, TRUE ~ .)} %>%
as.integer ))
# A tibble: 5 x 4
# S1 S2 S3 S4
# <int> <int> <int> <int>
#1 45 55 45 49
#2 53 45 45 45
#3 55 45 45 45
#4 45 45 51 45
#5 54 45 55 55
Or create a temporary object within {}
and apply case_when
on it或者在
{}
中创建一个临时 object 并在其上应用case_when
df1 %>%
mutate(across(everything(), ~ {
tmp <- round(. * 10 ) + 50
as.integer(case_when(tmp < 45 ~ 45, tmp > 55 ~ 55, TRUE ~ tmp))
}))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.