2016-06-30 14 views
1

Ich möchte eine Variable innerhalb jeder Gruppe zu standardisieren. Ich stoße in Schwierigkeiten, wenn ich die skalierte Variable später in einem Regressionsmodell benutze, wenn ich die Daten mit dplyr aufbereite. Dies ist jedoch für plyr nicht der Fall. Weiß jemand warum?Fehler bei der Standardisierung der Variablen pro Gruppe mit 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) 

Ergebnisse sind in Ordnung, alles funktioniert wie erwartet.

# standardize using mutate from dplyr 

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

lm(mpg_scaled ~ cyl, data=df2) 

Dies wirft einen Fehler (übersetzt aus Deutsch):

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

Auch wenn die Variable mpg_scaled Zugriff auf nur wenige Einträge angezeigt werden.

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 

Was ist los?

+2

Versuchen Sie 'str (df2)' oder 'dim (df2 $ mpg_skaliert)', um zu sehen, was los ist - Sie haben eine Matrix dort. Sie können es zum Beispiel mit 'c (scale (mpg))' oder 'as.vector (scale (mpg))' reparieren. Obwohl sie aus irgendeinem Grund Attribute nicht fallen lassen, während sie innerhalb von 'mutate' verwendet werden - noch ein weiterer peinlicher dplyr Seiteneffekt, denke ich. –

+1

Es könnte sich auf [dieses Problem] (https://github.com/hadley/dplyr/issues/1918) und/oder die darin referenzierten beziehen. – Henrik

Antwort

0

Sie entpacken gerade die skalierte Variable ein bisschen falsch. Prüfen Sie es mit:

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

Welche druckt:

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 ... 

Da mpg_scaled ist eine Matrix, keine Liste. So sollte das funktionieren:

Verwandte Themen