2015-03-14 1 views
1

У меня есть кадр данных с коэффициентом (grpfactor). Моя цель состоит в том, чтобы вычислить остатки, устанавливая модель lm отдельно в каждой группе и сохраняя их в исходном фрейме данных.ddply ошибка? (Добавление остатков lm, вычисленных в группах обратно в исходный кадр данных)

Модель должна быть указана во время выполнения (т. Е. Не может быть фиксированной строкой).

Я нашел this answer

ddply(d,.(g1,g2),transform,z= predict(lm(y ~ x))) 

Это, кажется, работает с статический определенной формулой, но если я поставил код внутри функции и использовать переменную строку вместо строкового литерала (константа), он терпит неудачу - - Зачем??

d <- data.frame(x = rnorm(20), 
      y = rnorm(20), 
      g1 = c(rep('a', 10), rep('b', 10)), 
      g2 = rep(c(rep('c', 5), rep('d', 5)), 2)) 


myfunc = function(d) { 
xx = "y ~ x" 
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx)))) 
return(retval) 
} 

# This fails: 
d.new = myfunc(d) 

# With the error: 
#Error: error in evaluating the argument 'object' in selecting a 
#method for function 'predict': Error in as.formula(xx) : object 'xx' not 
#found 


# But this works, because it's not encased in a function: 
xx = "y ~ x" 
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx)))) 

#Now, with the variable "xx" defined two lines above this line, 
#the following will actually work now: 
d.new = myfunc(d) 

#But if we do this, it will fail again: 
rm(xx) 
d.new = myfunc(d) 

#ddply works inside a function, but only with a model specified 
#as a literal string: 
myfunc2 = function(d) { 
retval = ddply(d,.(g1,g2),transform,z= predict(lm(formula=as.formula("y ~ x")))) 
return(retval) 
} 
d.new2 = myfunc2(d) 

Как и в сторону, без as.formula, myfunc2 завершается с ошибкой:

#Error: error in evaluating the argument 'object' in selecting a method 
#for function 'predict': Error in eval(expr, envir, enclos) : object 'y' 
#not found 

Но тот же код работает без as.formula, если это не в функции.

Что происходит?

Edit: хорошо, вот где она становится действительно сумасшедшей: это работает (разница, я определяю модель в родительской среде с использованием < < -)

myfunc3 = function(d) { 
xx <<- "y ~ x" 
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx)))) 
return(retval) 
} 
myfunc3(d) 

ответ

0

Вы получаете ошибку:

Error: object of type 'closure' is not subsettable 

Потому что, когда ddply попытается разрешить t в локальной среде перед глобальной средой. Действительно, он обнаружил функцию транспонирования (замыкание) t, а не вашу глобальную переменную t. Вам нужно просто изменить что-то другое R встроенных функций (t, c, ..). Например, это будет работать:

xx <- "y ~ x" 

Полный пример:

d <- data.frame(x = rnorm(20), 
       y = rnorm(20), 
       g1 = c(rep('a', 10), rep('b', 10)), 
       g2 = rep(c(rep('c', 5), rep('d', 5)), 2)) 
xx <- "y ~ x" 
ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx)))) 

#   x   y g1 g2   z 
# 1 -0.2066509 -0.74159051 a c -0.21886198 
# 2 -0.9801753 1.38958373 a c 0.62214098 
# 3 -0.4626821 0.48195967 a c 0.05950415 
# 4 1.2255134 -1.72809777 a c -1.77596158 
# 5 -1.0922717 0.02898265 a c 0.74401621 
# 6 -1.4379229 0.96377879 a d 0.18312800 
+0

Похоже, я отметил, что ответил слишком рано! Как только я вложу ddply внутри функции, она больше не работает. Я редактирую исходный вопрос с помощью лучшего примера игрушек, чтобы продемонстрировать ошибку. – Dimitri

+0

@Dimitri это ошибка в 'ddply'. Вы можете увидеть [здесь] (http://stackoverflow.com/questions/3149150/ddply-run-in-a-function-looks-in-the-environment-outside-the-function) для более подробной информации – agstudy

Смежные вопросы