【问题标题】:Why eval parse cannot be used to evaluate string as formula为什么 eval parse 不能用于将字符串评估为公式
【发布时间】:2017-02-22 05:28:41
【问题描述】:

R 为什么 eval parse 不能用于计算字符串作为公式

在这个问题中,我想知道在 R 中是否可以将字符串评估为公式。 该公式应由 data.frame 中的两个以上预先存在的列组成, 这允许使用跨 data.frame 行的不同参数值来评估公式。

我有以下例子:

# 1) Loading data
data(mtcars)

# 2) Creates a string formula using two arguments ( ideal to use three or more arguments )
mtcars$formulafx <- sprintf( 'mean( mtcars[mtcars[,2] == %s & mtcars[,10] == %i , 1] )' , mtcars$cyl , mtcars$gear )

 # 3) Incorrect result and really slow when used with only one argument formula
mtcars$resultsfx <- eval( parse( text = mtcars$formulafx ) )   

我一直在互联网上搜索类似的问题。 我发现以下是相关的: Updating a data.frame column with eval function

我已经使用as.formula 函数进行了相同的测试,但也没有结果。

我想确定:

  • 这种方法在 R 中根本不可能。
  • R 中还有其他解决方案。

================================

编辑:

感谢 Sathish 的解决方案。它可以工作,但我已经在包含 101.815 行的 data.frame 中测试了这个解决方案,结果如下:

user  system elapsed 
165.46   11.45  177.11

差不多 3 分钟。在实践中,这并不是很好。我会感谢建议。

【问题讨论】:

  • 无论您在实际问题中实际尝试使用eval(parse... 做什么,我都会鼓励您考虑替代方案。几乎没有必要在 R 中使用这种编程方法。
  • R fortunes 106 and 181 抬起丑陋的脑袋!
  • 在我看来你只需要ave(mtcars$mpg,mtcars$cyl,mtcars$gear,FUN=mean)

标签: r parsing dataframe eval


【解决方案1】:

使用lapply

unlist( lapply( mtcars$formulafx, function( x ) eval( parse( text = x ) ) ) )
# [1] 19.750 19.750 26.925 19.750 15.050 19.750 15.050 26.925 26.925 19.750 19.750 15.050 15.050
# [14] 15.050 15.050 15.050 15.050 26.925 26.925 26.925 21.500 15.050 15.050 15.050 15.050 26.925
# [27] 28.200 28.200 15.400 19.700 15.400 26.925

使用sapply

sapply( mtcars$formulafx, function( x ) eval( parse( text = x ) ) )
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 4 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 4 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 3 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 3 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 4 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 4 , 1] ) 
# 19.750 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 3 , 1] ) 
# 21.500 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 3 , 1] ) 
# 15.050 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 5 , 1] ) 
# 28.200 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 5 , 1] ) 
# 28.200 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 5 , 1] ) 
# 15.400 
# mean( mtcars[mtcars[,2] == 6 & mtcars[,10] == 5 , 1] ) 
# 19.700 
# mean( mtcars[mtcars[,2] == 8 & mtcars[,10] == 5 , 1] ) 
# 15.400 
# mean( mtcars[mtcars[,2] == 4 & mtcars[,10] == 4 , 1] ) 
# 26.925 

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 2014-09-08
    • 1970-01-01
    • 2021-09-04
    • 2018-05-06
    相关资源
    最近更新 更多