2014-10-06 2 views
2

В dplyr::do() есть ли способ доступа к переменным в контексте .data как и для других функций dplyr? Например, скажем, у меня есть кадр данных:dplyr do() без местоимения точки?

> dd <- data.frame(a=1:5) 

mutate(), а также другие функции, работает так, что выражения вычисляются в контексте фрейма данных:

> mutate(dd,a2=a*2) 
    a a2 
1 1 2 
2 2 4 
3 3 6 
4 4 8 
5 5 10 

Но не do:

> do(dd,data.frame(a2=a[1:2]*2)) 
Error in eval(expr, envir, enclos) : object 'a' not found 

Я могу достичь своей цели с помощью with() и точечного местоимения:

> do(dd,with(.,data.frame(a2=a[1:2]*2))) 
    a2 
1 2 
2 4 

Я также не знаю, почему это не работает:

> do(dd,function(X) data.frame(a2=X$a[1:2]*2)) 
Error: Result must be a data frame 

Вопросы:

  1. Есть ли логика, почему такое поведение (сфера) отличается от mutate, select и т. д.
  2. Есть ли элегантное решение или у меня есть , чтобы продолжать использовать with(), если я не хочу продолжать использовать .$variablename в выражении?
  3. Почему работа анонимного не работает? Кажется, что это работает here, но не знаю, почему мой случай отличается.

ответ

3
  1. mutate, select и т.д. специализированные функции, разработанные, чтобы иметь аргумент данных первый, которые работают с трубопроводами magrittr и помочь с нестандартной оценкой. do - более общая функция, которая не может делать те же предположения.

  2. Это зависит от того, что вы пытаетесь сделать. Если вы используете функцию с нестандартной оценкой, вам нужно будет только предоставить. один раз.

Например:

do(dd, transform(.,a2=a*2)[1:2,]["a2"]) 
    a2 
1 2 
2 4 

Но это не лучше, чем with действительно. Лучший код гольф будет:

do(dd, data.frame(a2=.$a[1:2]*2)) 
    a2 
1 2 
2 4 

Но это зависит от того, как часто вы хотите, чтобы обратиться к первоначальному data.frame. Возможно, вам будет проще и понятнее использовать специальные функции с трубопроводом для этой задачи.

  1. Вам нужно позвонить анонимной функции, иначе просто верните определение функции.

Как так:

do(dd,{function(X) data.frame(a2=X$a[1:2]*2)}(.)) 
    a2 
1 2 
2 4