2017-08-07 4 views
1

Ich bin nicht sicher, ob der Titel gut formuliert ist, aber hier ist die Situation:eine beliebige Anzahl von neuen Spalten erstellen in R mit dplyr

Ich habe einen Metadaten-Datensatz, die eine beliebige Anzahl von Zeilen haben kann in es, zum Beispiel:

Control_DF <- cbind.data.frame(
    Scenario = c("A","B","C") 
    ,Variable = c("V1","V2","V3") 
    ,Weight = c("w1","w2","w3") 
) 

die Daten in Control_DF enthaltenen Verwendung, ich möchte eine neue Version von jeder Variable auf meinem Haupt-Datensatz erstellen, wo ich die Variable durch das Gewicht multiplizieren. Also, wenn mein Haupt-Datensatz sieht wie folgt aus:

Main_Data <- cbind.data.frame(
    V1 = c(1,2,3,4) 
    ,V2 = c(2,3,4,5) 
    ,V2 = c(3,4,5,6) 
    ,w1 = c(0.1,0.5,1,0.8) 
    ,w2 = c(0.2,1,0.3,0.6) 
    ,w2 = c(0.3,0.7,0.1,0.2) 
) 

Dann in Open Source, was ich will so aussieht tun:

New_Data <- Main_Data %>% 
    mutate(
    weighted_V1 = V1 * w1 
    ,weighted_V2 = V2 * w2 
    ,weighted_V3 = V3 * w3 
) 

Ich brauche aber eine Möglichkeit, nicht diese harte Kodierung, und so, dass die Anzahl der Variablen, auf die Bezug genommen wird, beliebig ist.

Kann mir jemand helfen?

+0

was ist die Logik, wenn Sie nicht wollen, zu hart Code? – mtoto

+0

In meinem Beispiel haben wir V1-V3, aber in Anwendung dieser könnte ich V1 - V10, oder V1 - V76, etc .. Die Schönheit von dplyr ist prägnant, lesbaren Code, aber ich habe Mühe, das zu erweitern Problem. Ich könnte lappig oder so etwas machen, aber ich denke, es wird weniger effizient sein, und es ist sicherlich weniger lesbar, was für mich weniger wünschenswert ist. – TomFromWales

+0

Wenn ich irgendwie "gewichtet_V1 = V1 * w1, ..., gewichtet_Vn = Vn * wn" in eine Zeichenkette schreiben und dann "einfügen und ausführen" könnte das in die Mutate-Funktion, die nett wäre! – TomFromWales

Antwort

0

In Basis R mit lapply, Map und cbind Sie wie folgt tun könnte:

# with Control_DF create a list with pairs of <varName,wgt> 

controlVarList = lapply(Control_DF$Scenario,function(x) 

as.vector(as.matrix(Control_DF[Control_DF$Scenario==x,c("Variable","Weight")])) 

) 

controlVarList 
#[[1]] 
#[1] "V1" "w1" 
# 
#[[2]] 
#[1] "V2" "w2" 
# 
#[[3]] 
#[1] "V3" "w3" 


# A custom function for multiplication of both columns 

fn_weightedVars = function(x) { 

# x = c("V1","w1"); hence x[1] = "V1",x[2] = "w2" 
# reference these columns in Main_Data and do scaling 
wgtedCol = matrix(Main_Data[,x[1]] * Main_Data[,x[2]],ncol=1) 

#rename as required 
colnames(wgtedCol)= paste0("weighted_",x[1]) 

#return var 
wgtedCol 


} 


#call function on each each list element 

scaledList = Map(fn_weightedVars ,controlVarList) 

Ausgang: es

scaledDF = do.call(cbind,scaledList) 

#combine datasets 
New_Data = data.frame(Main_Data,scaledDF) 
New_Data 
# V1 V2 V3 w1 w2 w3 weighted_V1 weighted_V2 weighted_V3 
#1 1 2 3 0.1 0.2 0.3   0.1   0.4   0.9 
#2 2 3 4 0.5 1.0 0.7   1.0   3.0   2.8 
#3 3 4 5 1.0 0.3 0.1   3.0   1.2   0.5 
#4 4 5 6 0.8 0.6 0.2   3.2   3.0   1.2 
Verwandte Themen