簡體   English   中英

從字符串中提取函數或對象,然后使用Magrittr / Dplyr對其進行管道處理

[英]Extracting Function or Objects from a String and then Piping Them with Magrittr/Dplyr

我正在嘗試編寫一些代碼,在其中可以將給定字符串作為函數或對象讀取,然后通過管道傳遞。 我以為eval(parse())將是最自然的選擇,但至少具有某些功能,它無法與管道結合正確讀取字符串。 例如,假設我有兩個要表達的表達式和數字字符串:

 first <- "1"
 second <- "seq(10,2)"

輸出應與通過管道傳遞的輸出相同: 1 %>% seq(10,2)seq(1,10,2)

相反,我得到了錯誤,

eval(。,parse(text = second))中的錯誤:嘗試執行以下操作時,類型為'expression'的'envir'參數無效:

  eval(parse(first)) %>%
      eval(parse(second))

當我嘗試先將它們分配給命名對象然后通過管道傳輸它們時,我收到一條錯誤消息,指出找不到第二個對象:

  the.ex <- eval(parse(first))
  that.ex <- eval(parse(second))

   the.ex %>%
       that.ex

當我嘗試使用其他各種表達式/對象時,有時它可以工作(例如lm(cars) - cars%>%lm ),但是在大多數情況下,我會收到與上述類似的錯誤。 我如何才能做到這一點,以便它適用於可能從字符串中拉出的各種表達式/對象?

首先讓我警告您,將代碼存儲為字符串通常不是一件非常安全的事情,我們會盡量避免這樣做。

您的方法不起作用的原因是,您將管道eval()eval()函數,而不是eval函數的結果。 另外,您還希望延遲第二項的評估,直到將數據輸入到管道中為止。

您將需要先構建完整的管道表達式,然后再對其進行評估。 使用基數R做到這一點的一種方法是bquote()函數。 例如

library(matrittr)
eval(bquote(.(parse(text=first)[[1]]) %>% .(parse(text=second)[[1]])))
# [1] 1 3 5 7 9

刪除eval() ,您可以看到它首先構建了您要查找的表達式

bquote(.(parse(text=first)[[1]]) %>% .(parse(text=second)[[1]]))
# 1 %>% seq(10, 2)

使用rlang ,您可能會執行以下操作

library(rlang)
eval_tidy(expr(!!parse_expr(first) %>% !!parse_expr(second)))

同樣,您只需要確保首先構建完整的表達式即可。

將運算符與表達式連接的更通用的解決方案可能看起來像這樣

join_exprs <- function(exprs, op=`+`) {
  op <- ensym(op)
  N <- length(exprs)
  new_call <- exprs[[1]]
  for(x in exprs[-1]) {
    new_call <- expr((!!op)(!!new_call,!!x))
  }
  new_call
}

join_exprs(parse_exprs(c(first, second)), `%>%`)
# 1 %>% seq(10, 2)

這可以縮放到任意數量的表達式

join_exprs(parse_exprs(c("5", "exp", "round(2)")), `%>%`)
# 5 %>% exp %>% round(2)

您可以使用eval()它們。

我不確定如何解決這一問題。 目前,我可以執行以下操作:

first <- "1"
second <- "seq(10,2)"

>eval(parse(text = first))
[1] 1 #output

eval(parse(text = second))
[1] 10  9  8  7  6  5  4  3  2 #output

但是我無法將它們連接在一起。 我懷疑這是因為結果未通過管道傳遞到正確的位置:

parse(text = second)
expression(seq(10,2)) #output

您希望它在場景后面執行此操作:

expression(seq(., 10, 2)) #the . is the piped result

但是實際上是這樣做的:

expression(., seq(10,2))

因為除非另有說明,否則輸出總是通過管道傳遞到第一個變量的位置。

希望其他人可以幫助您解決此問題。

暫無
暫無

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

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