簡體   English   中英

R:使用字符串作為參數來改變dplyr中的動詞

[英]R: Using a string as an argument to mutate verb in dplyr

我正在構建一個閃亮的應用程序,需要允許用戶定義用於繪圖的新變量。 具體來說,我想允許用戶定義一個在mutate動詞中使用的表達式。 服務器接收表達式作為文本,我想知道如何使mutate在dplyr 0.7中執行它。 我可以使用mutate_使其工作(部分),但現在已棄用。 它還將新列名稱定義為整個表達式而不是新變量

這是一個可重復的例子:

input_from_shiny <- "Petal.ratio = Petal.Length/Petal.Width"
iris_mutated <- iris %>% mutate_(input_from_shiny)

這給出了以下內容

> head(iris_mutated)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Petal.ratio = Petal.Length/Petal.Width
1          5.1         3.5          1.4         0.2  setosa                                   7.00
2          4.9         3.0          1.4         0.2  setosa                                   7.00
3          4.7         3.2          1.3         0.2  setosa                                   6.50
4          4.6         3.1          1.5         0.2  setosa                                   7.50
5          5.0         3.6          1.4         0.2  setosa                                   7.00
6          5.4         3.9          1.7         0.4  setosa                                   4.25

從技術上講,我可以使用正則表達式從字符串中提取新的變量名並相應地重命名新列,但我想知道使用最新的dplyr版本實現它的正確方法是什么(正在閱讀https://cran.r-project .org / web / packages / dplyr / vignettes / programming.html ,但無法弄清楚)

我們可以使用rlang::parse_quosure() !! (bang bang)產生相同的結果:

  • parse_quosure :解析提供的字符串並將其轉換為quosure

  • !! :取消引用一個quosure,以便可以通過tidyeval動詞進行評估

請注意, parse_quosure()已被軟棄用,並根據其文檔在rlang 0.2.0重命名為parse_quo() 如果我們使用parse_quo() ,我們需要為quosures指定環境,例如parse_quo(input_from_shiny, env = caller_env())

library(rlang)
library(tidyverse)

input_from_shiny <- "Petal.ratio = Petal.Length/Petal.Width"
iris_mutated <- iris %>% mutate_(input_from_shiny)

iris_mutated2 <- iris %>% 
  mutate(!!parse_quosure(input_from_shiny))
head(iris_mutated2)

#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
#>   Petal.ratio = Petal.Length/Petal.Width
#> 1                                   7.00
#> 2                                   7.00
#> 3                                   6.50
#> 4                                   7.50
#> 5                                   7.00
#> 6                                   4.25


identical(iris_mutated, iris_mutated2)
#> [1] TRUE

編輯:分離LHS和RHS

lhs <- "Petal.ratio"
rhs <- "Petal.Length/Petal.Width"

iris_mutated3 <- iris %>% 
  mutate(!!lhs := !!parse_quosure(rhs))
head(iris_mutated3)

> head(iris_mutated3)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa
  Petal.ratio
1        7.00
2        7.00
3        6.50
4        7.50
5        7.00
6        4.25

reprex包 (v0.2.0)於2018-03-24創建。

Package friendlyeval是一個簡化的界面,用於整理eval,試圖在這些情況下使事情變得更加直接。

將您的字符串拆分為兩個,您將獲得要用作列名的字符串的一部分以及您希望用作表達式的字符串的一部分。 所以你可以寫:

library(friendlyeval)
library(dplyr)
lhs <- "Petal.ratio"
rhs <- "Petal.Length/Petal.Width"

iris_mutated3 <- 
  iris %>% 
  mutate(!!treat_string_as_col(lhs) := !!treat_string_as_expr(rhs))
head(iris_mutated3)

通過使用lhs上的函數,您可以檢查lhs可以解析為普通列名。

可以使用RStudio插件隨時將friendlyeval代碼轉換為簡潔的eval代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM