R (статистическая) ошибка с использованием transformBy(), часть пакета doBy
Я думаю, что при использовании transformBy(), части пакета doBy для R. я получаю ошибку определения области охвата. Вот простой пример проблемы:
> library(doBy)
>
> test.data = data.frame(
+ herp = c(1,2,3,4,5),
+ derp = c(2,3,1,3,5)
+ )
>
> transformData = function(data){
+
+ five = 5
+
+ transformBy(
+ ~ herp,
+ data=data,
+ sum=herp + derp + five
+ )
+ }
>
> transformData(test.data)
Error in eval(expr, envir, enclos) : object 'five' not found
Когда я запускаю transformBy() в рамках под-области (неглобальная область), локальные переменные или функции, по-видимому, не доступны для использования в transformBy. Если, с другой стороны, я определяю эти переменные или функции глобально, они становятся доступными. Вот несколько измененный пример, который работает:
> library(doBy)
>
> test.data = data.frame(
+ herp = c(1,2,3,4,5),
+ derp = c(2,3,1,3,5)
+ )
>
> five = 5
>
> transformData = function(data){
+ transformBy(
+ ~ herp,
+ data=data,
+ sum=herp + derp + five
+ )
+ }
>
> transformData(test.data)
herp derp sum
1 1 2 8
2 2 3 10
3 3 1 9
4 4 3 12
5 5 5 15
Я что-то не понимаю о том, как transformBy должен работать или что-то сломано?
Версии:
- ubuntu: 8.04 (x64)
- R: 2.10.1
- doBy: 4.0.5
Ответы
Ответ 1
Это четко задокументировано на странице справки? transformBy, и поэтому
не ошибка.
Подробнее:
The ... arguments are tagged vector expressions, which are
evaluated in the data frame data. The tags are matched against
names(data), and for those that match, the value replace the
corresponding variable in data, and the others are appended to
data.
Просто сделайте объект "пять" частью данных data.frame и "
он будет работать так, как вы ожидаете. В настоящее время функция пытается
оценить "пять" в "data" data.frame, что, конечно, не проходит.
Ответ 2
Это проблема, возникающая различными способами. По-видимому, происходит что-то странное со шкалой в R.
edit: Это не область видимости в R, которая отличается от того, что я наивно ожидал, но один из transformBy(). См. Ответ Эрика.
Я обойду его, назначив временную среду в глобальной среде, например:
transformData = function(data){
temp_env <<- new.env(hash=T) #hashed environment for easy access
temp_env$five = 5
out <- transformBy(
~ herp,
data=data,
sum=herp + derp + temp_env$five
)
rm(temp_env,envir=.GlobalEnv) # cleanup
return(out)
}
Ответ 3
Я считаю это ошибкой в функции transformBy
. Если вы посмотрите на источник transformBy
, он создает подфункцию под названием transform2
, которая сначала оценивает последний аргумент в контексте фреймворка данных, а parent.frame() - как окружающая среда. Затем он вызывает lapply
на transform2
.
Так как R использует семантику лексической семантики (см. http://cran.r-project.org/doc/manuals/R-intro.html#Scope), эффективная иерархия областей data
, затем lapply
затем глобальная. Я думаю, что правильное исправление заключается в том, чтобы добавить инструкцию формы pf <- parent.frame()
вне определения transform2
, а затем ссылку pf
в инструкции eval
.