如何动态创建具有整洁评估的列?
How to dynamically create columns with tidy evaluation?
我想使用特定模式创建变量。我需要在 mutate 函数中包含变量名称作为整洁的评估。我在下面做了一个自定义示例:
iris %>%
rename(Sepal = Sepal.Width, Petal = Petal.Width) %>%
mutate_at(c('Sepal', 'Petal'), list(test = ~ . / !!sym(paste0(., '.Length'))))
在较新版本的dplyr
中,我们可以使用across
library(dplyr)
library(stringr)
iris %>%
rename(Sepal = Sepal.Width, Petal = Petal.Width) %>%
mutate(across(c('Sepal', 'Petal'), ~
./get(str_c(cur_column(), '.Length')), .names = '{.col}_test'))
-输出
# Sepal.Length Sepal Petal.Length Petal Species Sepal_test Petal_test
#1 5.1 3.5 1.4 0.2 setosa 0.6862745 0.14285714
#2 4.9 3.0 1.4 0.2 setosa 0.6122449 0.14285714
#3 4.7 3.2 1.3 0.2 setosa 0.6808511 0.15384615
#4 4.6 3.1 1.5 0.2 setosa 0.6739130 0.13333333
#5 5.0 3.6 1.4 0.2 setosa 0.7200000 0.14285714
#6 5.4 3.9 1.7 0.4 setosa 0.7222222 0.23529412
#7 4.6 3.4 1.4 0.3 setosa 0.7391304 0.21428571
#8 5.0 3.4 1.5 0.2 setosa 0.6800000 0.13333333
# ...
我们不需要为了除法而重命名。也可以通过保留原来的列名
来实现
iris %>%
mutate(across(ends_with('Width'), ~
./get(str_replace(cur_column(), 'Width', 'Length')),
.names = '{.col}_test'))
.
returns 值而不是列名。因此,paste0(., '.Length')
将粘贴子字符串 .Length
与相应的列值
对于这种情况,我发现使用 base R 更简单:
df <- iris
cols <- c('Sepal', 'Petal')
df[paste0(cols,'.res')] <- df[paste0(cols,'.Width')]/df[paste0(cols,'.Length')]
head(df)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.res Petal.res
#1 5.1 3.5 1.4 0.2 setosa 0.6862745 0.1428571
#2 4.9 3.0 1.4 0.2 setosa 0.6122449 0.1428571
#3 4.7 3.2 1.3 0.2 setosa 0.6808511 0.1538462
#4 4.6 3.1 1.5 0.2 setosa 0.6739130 0.1333333
#5 5.0 3.6 1.4 0.2 setosa 0.7200000 0.1428571
#6 5.4 3.9 1.7 0.4 setosa 0.7222222 0.2352941
我想使用特定模式创建变量。我需要在 mutate 函数中包含变量名称作为整洁的评估。我在下面做了一个自定义示例:
iris %>%
rename(Sepal = Sepal.Width, Petal = Petal.Width) %>%
mutate_at(c('Sepal', 'Petal'), list(test = ~ . / !!sym(paste0(., '.Length'))))
在较新版本的dplyr
中,我们可以使用across
library(dplyr)
library(stringr)
iris %>%
rename(Sepal = Sepal.Width, Petal = Petal.Width) %>%
mutate(across(c('Sepal', 'Petal'), ~
./get(str_c(cur_column(), '.Length')), .names = '{.col}_test'))
-输出
# Sepal.Length Sepal Petal.Length Petal Species Sepal_test Petal_test
#1 5.1 3.5 1.4 0.2 setosa 0.6862745 0.14285714
#2 4.9 3.0 1.4 0.2 setosa 0.6122449 0.14285714
#3 4.7 3.2 1.3 0.2 setosa 0.6808511 0.15384615
#4 4.6 3.1 1.5 0.2 setosa 0.6739130 0.13333333
#5 5.0 3.6 1.4 0.2 setosa 0.7200000 0.14285714
#6 5.4 3.9 1.7 0.4 setosa 0.7222222 0.23529412
#7 4.6 3.4 1.4 0.3 setosa 0.7391304 0.21428571
#8 5.0 3.4 1.5 0.2 setosa 0.6800000 0.13333333
# ...
我们不需要为了除法而重命名。也可以通过保留原来的列名
来实现iris %>%
mutate(across(ends_with('Width'), ~
./get(str_replace(cur_column(), 'Width', 'Length')),
.names = '{.col}_test'))
.
returns 值而不是列名。因此,paste0(., '.Length')
将粘贴子字符串 .Length
与相应的列值
对于这种情况,我发现使用 base R 更简单:
df <- iris
cols <- c('Sepal', 'Petal')
df[paste0(cols,'.res')] <- df[paste0(cols,'.Width')]/df[paste0(cols,'.Length')]
head(df)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.res Petal.res
#1 5.1 3.5 1.4 0.2 setosa 0.6862745 0.1428571
#2 4.9 3.0 1.4 0.2 setosa 0.6122449 0.1428571
#3 4.7 3.2 1.3 0.2 setosa 0.6808511 0.1538462
#4 4.6 3.1 1.5 0.2 setosa 0.6739130 0.1333333
#5 5.0 3.6 1.4 0.2 setosa 0.7200000 0.1428571
#6 5.4 3.9 1.7 0.4 setosa 0.7222222 0.2352941