将方程作为参数传递给函数

时间:2017-04-27 13:52:28

标签: r

我被告知将方程式作为字符串并对其进行评估是不好的做法。如何创建一个函数,该函数采用等式并在没有字符串版本的情况下对其进行评估,而不使用第三方软件包?

这是我的功能:

replaceFormula <- function(df, column, formula){
  df[column] <- eval(parse(text=formula), df)
  return(df)
}

这是我的用例:

set.seed(24)
dataset <- matrix(sample(c(NA, 1:5), 25, replace = TRUE), 5)
df <- as.data.frame(dataset)
replaceFormula(df, 'V5', 'V3+V4')

更新

条件也可以吗? 我的示例函数:

replaceFactor <- function(df, column, condition, what){
  df[column] <- sapply(df[column],function(x) ifelse(eval(parse(text=condition), df), what, x))
  return(df)
}

我的用例:

set.seed(24)
dataset <- matrix(sample(c(NA, 1:5), 25, replace = TRUE), 5)
df <- as.data.frame(dataset)
replaceFactor(df, 'V5', 'V1==1', 'GOOD')

2 个答案:

答案 0 :(得分:3)

看起来你自己制作了transform

的kludgey版本
> set.seed(24)
> dataset <- matrix(sample(c(NA, 1:5), 25, replace = TRUE), 5)
> df <- as.data.frame(dataset)
> transform(df, V5 = V3 + V4)
  V1 V2 V3 V4 V5
1  1  5  3  5  8
2  1  1  2  1  3
3  4  4  4 NA NA
4  3  4  4  3  7
5  3  1  1 NA NA

答案 1 :(得分:1)

我们可以将公式作为quosure传递,并通过在!!的devel版本中取消引用(UQdplyr)来对其进行评估(或即将发布{ {1}})

0.6.0

更新

根据OP的评论,我们还可以传递一个表达式来评估和更改基于该值的值

library(dplyr)
replaceFormula <- function(dat, Col, form){
      Col <- quo_name(enquo(Col))
      dat %>% 
          mutate(UQ(Col) := UQ(form))
  }


replaceFormula(df, V5, quo(V3 + V4)) 
#   V1 V2 V3 V4 V5
#1  1  5  3  5  8
#2  1  1  2  1  3
#3  4  4  4 NA NA
#4  3  4  4  3  7
#5  3  1  1 NA NA

replaceFormulaNew <- function(dat, Col, form, what){ Col <- enquo(Col) ColN <- quo_name(Col) what <- quo_name(enquo(what)) dat %>% mutate(UQ(ColN) := ifelse(UQ(form), what, UQ(Col))) } replaceFormulaNew(df, V5, quo(V1==1), GOOD) # V1 V2 V3 V4 V5 #1 1 5 3 5 GOOD #2 1 1 2 1 GOOD #3 4 4 4 NA 4 #4 3 4 4 3 <NA> #5 3 1 1 NA 1 replaceFormulaNew(df, V5, quo(V3 < V4), GOOD) # V1 V2 V3 V4 V5 #1 1 5 3 5 GOOD #2 1 1 2 1 3 #3 4 4 4 NA <NA> #4 3 4 4 3 <NA> #5 3 1 1 NA <NA> 接受输入参数并将其转换为enquo,而quosure将其转换为字符串以便在quo_name中进行评估,以将评估后的输出分配给指定的列输入