2017-12-04 4 views
1

Ich habe einen sehr großen Datenrahmen und eine Reihe von Anpassungskoeffizienten, die ich auf bestimmte Jahre anwenden möchte, wobei jeder Koeffizient auf einen einzigen angewandt wird ein Jahr. Der folgende Code versucht, für jede Zeile den richtigen Koeffizienten auszuwählen und gibt einen Vektor mit dat in den nicht betroffenen Jahren und dat mal diesen Koeffizienten in den ausgewählten Jahren zurück, der dat ersetzen soll.dplyr: Kann eine Funktion mit dem Namen inner mutate das Element einer Spalte aus der aktuellen Zeile finden

year <- rep(1:5, times = c(2,2,2,2,2)) 
dat <- 1:10 
df <- tibble(year, dat) 
adjust = c(rep(0, 4), rep(c(1 + 0.1*1:3), c(2,2,2))) 
df %>% mutate(dat = ifelse(year < 5, year, dat*adjust[[year - 2]])) 

Wenn ich dies zu tun bekommen, erhalte ich folgende Fehlermeldung:

Evaluation error: attempt to select more than one element in vectorIndex. 

Ich bin mir ziemlich sicher, dass dies liegt daran, dass der Eingabe-Operator [[ behandeln year wie das gesamte Vektor Jahr statt Jahr die aktuelle Zeile, so gibt es dann eine vektorisierte Subtraktion, woraufhin [[ auf den vektorwertigen Index drosselt.

Ich weiß, dass es viele Möglichkeiten gibt, dieses Problem zu lösen. Ich habe eine besonders hässliche Art und Weise mit verschachtelten Ifelse arbeitet jetzt. Meine Frage ist: Gibt es irgendeinen Weg, das zu tun, was ich auf eine r- und dipyrdiomatische Weise zu tun versuchte? In gewisser Weise scheint dies ein Filter- oder group_by-Problem zu sein, da wir Zeilen oder Gruppen von Zeilen als unterschiedliche Entitäten behandeln wollen, aber ich habe keinen Weg gefunden, dies zu tun, der sauberer ist.

Es scheint so, als gäbe es einige Funktionen, die einfacher zu definieren oder zu denken sind, als Zeile für Zeile und nicht als das Produkt ganzer Vektoren. Ich könnte einen einzelnen Vektor erzeugen, der die korrekte Anpassung für jedes Jahr enthält, aber da die Anzahl der Zeilen pro Jahr variiert, müsste ich immer noch einen mehrwertigen Bedingungstest anwenden, um diesen Vektor zu konstruieren, so dass das gleiche Problem auftritt.

Oder nicht?

+1

Wie ordne Sie 'adjust' zu' year'? Sie haben fünf verschiedene Jahre, aber nur drei 'adjust' Werte. – Psidom

+0

Jahrkarten Jahr für Jahr weniger als - nun, eigentlich weniger als 3, nicht 2. Lassen Sie mich das beheben. – andrewH

Antwort

2

Sie müssen [ anstelle von [[ für Vektorindexierung verwenden; Und auch year - 2 erzeugt einen negativen Index, was zu weiteren Problemen führen wird; Wenn Sie year zu adjust von Indexpositionen zuordnen möchten, können Sie replace mit einem mask verwenden, die die year zeigt modifiziert werden:

df %>% 
    mutate(dat = { 
     mask = year > 2; 
     replace(year, mask, dat[mask] * adjust[year[mask] - 2]) 
    }) 
# A tibble: 10 x 2 
# year1 dat1 
# <int> <dbl> 
# 1  1 1.0 
# 2  1 1.0 
# 3  2 2.0 
# 4  2 2.0 
# 5  3 5.5 
# 6  3 6.6 
# 7  4 8.4 
# 8  4 9.6 
# 9  5 11.7 
#10  5 13.0 
+0

Danke Psidom! Diese Replace-Funktion ist sehr praktisch - ich bin überrascht, dass ich sie noch nie zuvor gesehen habe. Ich habe gerade versucht, etwas Ähnliches mit left_join zu schreiben. Wenn ich dazu komme, nicht garantiert, vergleiche ich sie untereinander und poste die Ergebnisse hier. – andrewH

Verwandte Themen