2016-06-30 5 views
1

Я хочу стандартизировать переменную в каждой группе. У меня возникают проблемы при использовании масштабированной переменной в модели регрессии после подготовки данных с использованием dplyr. Однако это не относится к plyr. Кто-нибудь знает, почему?Ошибка при стандартизации переменной для каждой группы с использованием dplyr

library(plyr) 
library(dplyr) 

df <- mtcars[, c("cyl", "mpg")]  # keep two columns 

# standardize using ddply from plyr 

df1 <- ddply(df, .(cyl), function(x) { 
    x$mpg_scaled = scale(x$mpg) 
    x 
}) 

lm(mpg_scaled ~ cyl, data=df1) 

Результаты в порядке, все работает должным образом.

# standardize using mutate from dplyr 

df2 <- df %>% group_by(cyl) %>% 
    mutate(
    mpg_scaled = unlist(scale(mpg)) 
) 

lm(mpg_scaled ~ cyl, data=df2) 

Это выдает ошибку (в переводе с немецкого):

Error in model.frame.default(formula = mpg_scaled ~ cyl, data = df2, drop.unused.levels = TRUE) : 
    Variable lengths are different (found for 'cyl') 

Кроме того, при обращении к переменной mpg_scaled, только несколько записей показано на рисунке.

df2$mpg_scaled 
      [,1] 
[1,] 0.8648675 
[2,] 0.8648675 
[3,] -0.8567149 
[4,] 1.1400526 
[5,] 1.4062236 
[6,] -1.1302245 
[7,] -0.3124941 
[8,] -0.5019341 
[9,] -0.8567149 
[10,] -0.3734655 
[11,] -1.3366134 
attr(,"scaled:center") 
[1] 26.66364 
attr(,"scaled:scale") 
[1] 4.509828 

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

+2

Попробуйте 'str (df2)' или 'dim (df2 $ mpg_scaled)', чтобы посмотреть, что происходит, у вас есть матрица. Вы можете исправить это с помощью 'c (scale (mpg))' или 'as.vector (scale (mpg))' например. Хотя по какой-то причине они не отбрасывают атрибуты при использовании в 'mutate', но еще одна неудобная сторона dplyr влияет на меня. –

+1

Это может быть связано с [этой проблемой] (https://github.com/hadley/dplyr/issues/1918) и/или теми, на которые они ссылаются. – Henrik

ответ

0

Вы просто переустановите измененную переменную немного неправильно. Проверьте это с:

df %>% group_by(cyl) %>% 
+  mutate(
+   mpg_scaled = scale(mpg) 
+ ) %>% str 

который печатает:

Classes 'grouped_df', 'tbl_df', 'tbl' and 'data.frame': 32 obs. of 3 variables: 
$ cyl  : num 6 6 4 6 8 6 8 4 4 6 ... 
$ mpg  : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... 
$ mpg_scaled: num [1:11, 1] 0.865 0.865 -0.857 1.14 1.406 ... 
    ..- attr(*, "scaled:center")= num 26.7 
    ..- attr(*, "scaled:scale")= num 4.51 
- attr(*, "vars")=List of 1 
    ..$ : symbol cyl 
- attr(*, "labels")='data.frame': 3 obs. of 1 variable: 
    ..$ cyl: num 4 6 8 
    ..- attr(*, "vars")=List of 1 
    .. ..$ : symbol cyl 
    ..- attr(*, "drop")= logi TRUE 
- attr(*, "indices")=List of 3 
    ..$ : int 2 7 8 17 18 19 20 25 26 27 ... 
    ..$ : int 0 1 3 5 9 10 29 
    ..$ : int 4 6 11 12 13 14 15 16 21 22 ... 

Поскольку mpg_scaled является матрицей, а не список. Так что это должно сработать:

df2 <- df %>% group_by(cyl) %>% 
    mutate(
     mpg_scaled = scale(mpg)[,1] 
    ) 
Смежные вопросы