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

时间:2017-02-22 05:28:42

标签: r parsing dataframe eval

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.15行的data.frame中测试了这个解决方案,结果如下:

user  system elapsed 
165.46   11.45  177.11

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

1 个答案:

答案 0 :(得分:0)

使用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