我想根據給定的字符向量添加一個新列。例如,在下面的示例中,我想添加d定義的列expr:
library(magrittr)
data <- tibble::tibble(
a = c(1, 2),
b = c(3, 4)
)
expr <- "d = a b"
如下:
data %>%
dplyr::mutate(d = a b)
# # A tibble: 2 x 3
# a b d
# <dbl> <dbl> <dbl>
# 1 1 3 4
# 2 2 4 6
但是,在下面的代碼中,雖然計算本身(即添加)有效,但新列的名稱與我的預期不同。
data %>%
dplyr::mutate(!!rlang::parse_expr(expr))
# # A tibble: 2 x 3
# a b `d = a b`
# <dbl> <dbl> <dbl>
# 1 1 3 4
# 2 2 4 6
data %>%
dplyr::mutate(!!rlang::parse_quo(expr, env = rlang::global_env()))
# # A tibble: 2 x 3
# a b `d = a b`
# <dbl> <dbl> <dbl>
# 1 1 3 4
# 2 2 4 6
data %>%
dplyr::mutate(rlang::eval_tidy(rlang::parse_expr(expr)))
# # A tibble: 2 x 3
# a b `rlang::eval_tidy(rlang::parse_expr(expr))`
# <dbl> <dbl> <dbl>
# 1 1 3 4
# 2 2 4 6
如何正確使用 dplyr::mutate 中的運算式?
我的問題與此類似,但在我的示例中,新變數 ( d) 及其定義 ( a b) 在單個字符向量 ( expr) 中給出。
uj5u.com熱心網友回復:
讓我們首先看一下dplyr::mutate創建命名變數需要什么樣的運算式:我們需要一個命名串列,其中包含一個運算式,以使用給定的串列元素名稱基于該運算式創建變數。
library(tidyverse)
data <- tibble::tibble(
a = c(1, 2),
b = c(3, 4)
)
expr <- "d = a b"
# let's rewrite the string above as named list containing an expression.
expr2 <- list(d = expr(a b))
# this works as expected:
data %>%
mutate(!!! expr2)
#> # A tibble: 2 x 3
#> a b d
#> <dbl> <dbl> <dbl>
#> 1 1 3 4
#> 2 2 4 6
現在我們只需要一個函式,將字串轉換為包含等式右側運算式的命名串列。名稱必須在等式的左側。我們可以通過常規的字串操作來做到這一點。最后,我們需要將等式的右側從字串轉換為運算式。我們可以str2lang在這里使用base R。
create_expr_ls <- function(str_expr) {
expr_nm <- str_extract(str_expr, "^\\w ")
expr_code <- str_replace_all(str_expr, "(^\\w \\s?=\\s?)(.*)", "\\2")
set_names(list(str2lang(expr_code)), expr_nm)
}
expr3 <- create_expr_ls(expr)
data %>%
mutate(!!! expr3)
#> # A tibble: 2 x 3
#> a b d
#> <dbl> <dbl> <dbl>
#> 1 1 3 4
#> 2 2 4 6
由reprex 包(v0.3.0)于 2022-01-23 創建
uj5u.com熱心網友回復:
這些作業中的任何一個。第二個類似于第一個,但不需要rlang在搜索路徑上。如果d=零件不存在,則第三和第四也可以使用,expr在這種情況下使用默認名稱。最后一個僅使用基數 R,也是最短的。
data %>% mutate(within(., !!parse_expr(expr)))
data %>% mutate(within(., !!parse(text = expr)))
data %>% mutate(data, !!parse_expr(sprintf("tibble(%s)", expr)))
data %>% { eval_tidy(parse_expr(sprintf("mutate(., %s)", expr))) }
within(data, eval(parse(text = expr))) # base R
筆記
假設這個前提:
library(dplyr)
library(rlang)
# input
data <- tibble(a = c(1, 2), b = c(3, 4))
expr <- "d = a b"
uj5u.com熱心網友回復:
要獲得變異列的所需名稱,您仍然可以使用相同的語法并將結果分配給具有首選名稱的列。要獲取此名稱,您可以使用正則運算式查找之前的內容=,然后洗掉可能存在的任何前導或尾隨空格。
expr <- "x = a * b"
col_name <- trimws(str_extract(expr,"[^=] "))
data %>%
dplyr::mutate(!!col_name := !!rlang::parse_expr(expr))
# A tibble: 2 × 3
a b x
<dbl> <dbl> <dbl>
1 1 3 3
2 2 4 8
data %>%
dplyr::mutate(!!col_name := !!rlang::parse_quo(expr, env = rlang::global_env()))
# A tibble: 2 × 3
a b x
<dbl> <dbl> <dbl>
1 1 3 3
2 2 4 8
data %>%
dplyr::mutate(!!col_name := rlang::eval_tidy(rlang::parse_expr(expr)))
# A tibble: 2 × 3
a b x
<dbl> <dbl> <dbl>
1 1 3 3
2 2 4 8
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/420145.html
標籤:
下一篇:sapply多列和資料框
