2014-09-24 5 views
6

Diese Frage folgt eine andere auf group weighted means: Ich möchte gewichtete In-Gruppe-Durchschnittswerte mit data.table erstellen. Der Unterschied zur anfänglichen Frage besteht darin, dass die Namen der Variablen, die als Durchschnittswert gelten, in einem Zeichenfolgenvektor angegeben sind.Gewichtet bedeutet für mehrere Spalten, nach Gruppen (in einer data.table)

Die Daten:

df <- read.table(text= " 
      region state county weights y1980 y1990 y2000 
      1  1  1  10  100 200  50 
      1  1  2  5  50 100 200 
      1  1  3  120 1000 500 250 
      1  1  4  2  25 100 400 
      1  1  4  15  125 150 200 
      2  2  1  1  10  50 150 
      2  2  2  10  10  10 200 
      2  2  2  40  40 100  30 
      2  2  3  20  100 100  10 
", header=TRUE, na.strings=NA) 

Mit Rolands vorgeschlagene Antwort von oben genannten Frage:

library(data.table) 
dt <- as.data.table(df) 
dt2 <- dt[,lapply(.SD,weighted.mean,w=weights),by=list(region,state,county)] 

Ich habe einen Vektor mit Streichern, für die ich den innerhalb der Gruppe gewichteter Durchschnitt will dynamisch Spalten zu bestimmen.

colsToKeep = c("y1980","y1990") 

Aber ich weiß nicht, wie es für die data.table Magie als Argument zu übergeben.

Ich versuchte

dt[,lapply(
     as.list(colsToKeep),weighted.mean,w=weights), 
     by=list(region,state,county)]` 

aber ich bekomme dann:

Error in x * w : non-numeric argument to binary operator 

Nicht sicher, wie zu erreichen, was ich will.

Bonusfrage: Ich möchte, dass ursprüngliche Spaltennamen beibehalten werden, anstatt V1 und V2 zu erhalten.

Hinweis: Ich verwende Version 1.9.3 des Pakets data.table.

Antwort

8

Normalerweise, sollten Sie in der Lage zu tun:

dt2 <- dt[,lapply(.SD,weighted.mean,w=weights), 
      by = list(region,state,county), .SDcols = colsToKeep] 

das heißt, nur durch nur diese Spalten zu .SDcols bieten. Aber im Moment wird dies nicht funktionieren , in dem weights Spalte wird nicht verfügbar sein, weil es nicht in .SDcols angegeben ist.

Bis es behoben ist, können wir dies zu erreichen, wie folgt:

dt2 <- dt[, lapply(mget(colsToKeep), weighted.mean, w = weights), 
      by = list(region, state, county)] 
# region state county  y1980 y1990 
# 1:  1  1  1 100.0000 200.0000 
# 2:  1  1  2 50.0000 100.0000 
# 3:  1  1  3 1000.0000 500.0000 
# 4:  1  1  4 113.2353 144.1176 
# 5:  2  2  1 10.0000 50.0000 
# 6:  2  2  2 34.0000 82.0000 
# 7:  2  2  3 100.0000 100.0000 
+0

Bug noch vorhanden oder ist Der erste Ansatz wird nicht mehr empfohlen? Am 16. Dezember 2015, bekomme ich das: "Fehler in as.double (w): kann nicht zwingen 'Schließung' zu Vektor des Typs 'double''' – PatrickT

+1

Bug ist noch nicht behoben, sorry :-(. Sie könnte tun: 'dt [, lapply (mget (colsToKeep), gewichtete.Mean, w = Gewichte), von =. (Region, Bundesland, Land)]. Ihr Fehler scheint darauf hinzuweisen, dass Sie' as.double' verwenden mit einer Funktion als Eingabe (was nichts miteinander zu tun hat.) – Arun

+0

danke. Also im Wesentlichen ist Ihr Vorschlag, '' mget() '' anstatt '' as.list (.SD) [] '' oder?(Ich weiß, dass der Punkt, den Sie nach '' by = '' verwenden, eine Abkürzung für '' liste'' ist, so dass das Bit des Codes dasselbe ist wie Ihre Problemumgehung) (Über die Fehlermeldung glaube ich, ich kopiere nur -pasted die Daten des OP, aber nicht über einen data.frame gehen.) – PatrickT

0

Ich weiß nicht, data.table aber haben Sie in Betracht gezogen mit dplyr? Ich denke, dass es fast so schnell wie data.table

library(dplyr) 
df %>% 
    group_by(region, state, county) %>% 
    summarise(mean_80 = weighted.mean(y1980, weights), 
      mean_90 = weighted.mean(y1990, weights)) 
Source: local data frame [7 x 5] 
Groups: region, state 

    region state county mean_80 mean_90 
1  1  1  1 100.0000 200.0000 
2  1  1  2 50.0000 100.0000 
3  1  1  3 1000.0000 500.0000 
4  1  1  4 113.2353 144.1176 
5  2  2  1 10.0000 50.0000 
6  2  2  2 34.0000 82.0000 
7  2  2  3 100.0000 100.0000 
+0

Dank für Ihre Hilfe danken, aber ich brauche data.table zu verwenden, und auch Ihre Antwort wird nicht auf die neue Einschränkung meiner Frage, die ist, dass Spalten dynamisch durch einen Vektor spezifiziert werden müssen. – Peutch

+0

Mein schlechtes, ich hätte deinen Beitrag sorgfältiger lesen sollen. Wenn Sie sich für dplyr entscheiden, [hier] (http://stackoverflow.com/questions/26003574/r-dplyr-mutate-use-dynamic-variable-names) ein Beispiel, das hilfreich sein könnte – kferris10

Verwandte Themen