为什么不能使用 eval parse 将字符串作为公式求值
Why eval parse cannot be used to evaluate string as formula
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 分钟。实际上这并不是很好。我会感谢建议。
使用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
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 分钟。实际上这并不是很好。我会感谢建议。
使用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