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.