2017-11-22 4 views
2

Ich versuche, eine neue Spalte mit einem dynamisch erstellten Namen zu erstellen und füllen Sie das Feld mit einem Ausdruck, der andere dynamisch erstellte Variablen enthält. Betrachten Sie zum Beispiel den folgenden Datenrahmen.Dplyr - Dynamisch benannte Variablen mit anderen dynamisch benannten Variablen mutieren

ID multiplier value1_2015 value2_2015 value1_2016 value2_2016 
1   0.5    2    3    1    4 
2   1.0    2    4    5    1 

Ich möchte eine Funktion schreiben, die den Datenrahmen gegeben ist, und ein Jahr und wertet dann einen Ausdruck nur für die entsprechenden Jahre Variablen und speichert das Ergebnis in einer Spalte total_year genannt, wo year der Wert der Funktion gegeben. Zum Beispiel war, wenn der Ausdruck

multiplier * value1_year + value2_year und ich rief my_fun(df, 2016) sollte ich erhalten

ID multiplier value1_2015 value2_2015 value1_2016 value2_2016 total_2016 
1  0.5   2   3   1   4   4.5 
2  1.0   2   4   4   5   9 

Hier ist, was ich habe

my_fun <- function(df, year) { 

year <- enquo(year) 

total_header <- paste("total", quo_name(year), sep = "_") 
calc1_header <- paste("value1", quo_name(year), sep = "_") 
calc2_header <- paste("value2", quo_name(year), sep = "_") 

calc1_header <- enquo(calc1_header) 
calc2_header <- enquo(calc2_header) 

ret_table <- df %>% 
mutate(!!total_header := multiplier * !!calc1_header + !!calc2_header) 

return(ret_table) 

} 

Wenn ich das versuche ich, das erhalten folgende Error in mutate_impl(.data, dots) : Evaluation error: non-numeric argument to binary operator.

Ersetzen des Ausdrucks mit etwas wie nur !!total_header := !!calc1_header läuft ohne Fehler, erzeugt die Korrekt t Spaltenname, aber die Werte in der Spalte sind die Zeichenfolge "value1_2016", nicht die entsprechenden Werte aus der Spalte value1_2016.

+1

Sind Sie sicher, dass Sie nicht wollen,' für 'calc1_header', etc sym' statt' enquo'? – joran

+0

Sie brauchen den "enquo/quo_name" überhaupt nicht, weil 'Jahr' numerisch ist und stellen Sie sicher, dass Sie die geschweiften Klammern 'mutate (!! total_header: = multiplier * (!! calc1_header) + (!! calc2_header)) verwenden 'nach dem' calc1_header <- rlang :: sym (calc1_header) 'und' calc2_header' – akrun

+0

Da gehen wir, 'enquo' durch' rlang :: sym' für 'calc1_header' und' calc2_header' ersetzt. Vielen Dank! – ArzaanK

Antwort

2

Hier brauchen wir nicht die enquo/quo_name für 'Jahr', da wir einen numerischen Wert übergeben. Die Ausgabe von paste wird character Klasse sein, unter Verwendung sym von rlang (als @joran erwähnt) kann dies in Symbol umgewandelt und mit !! ausgewertet werden. Stellen Sie sicher, Klammern um die '!! calc1_header 'und' !! calc2_header‘zu bewerten das spezifische Objekt

my_fun <- function(df, year) { 

    total_header <- paste("total", year, sep = "_") 
    calc1_header <- rlang::sym(paste("value1", year, sep = "_")) 
    calc2_header <- rlang::sym(paste("value2", year, sep = "_")) 

df %>% 
     mutate(!!total_header := multiplier * (!!calc1_header) + (!!calc2_header)) 



} 

my_fun(df1, 2016) 
# ID multiplier value1_2015 value2_2015 value1_2016 value2_2016 total_2016 
#1 1  0.5   2   3   1   4  4.5 
#2 2  1.0   2   4   4   5  9.0 
0

reproduzieren helfen:

df1 <- structure(list(ID = 1:2, multiplier = c(0.5, 1), value1_2015 = c(2L, 2L), value2_2015 = 3:4, value1_2016 = c(1L, 5L), value2_2016 = c(4L, 1L)), .Names = c("ID", "multiplier", "value1_2015", "value2_2015", "value1_2016", "value2_2016"), row.names = c(NA, -2L), class = c("data.table", "data.frame"))

Verwandte Themen