2017-08-07 120 views
1

我不知道如果标题的措辞以及新列的任意数字,但这里的情况是:创建R中使用dplyr

我有一个元数据集,它可以有任意数量的行在里面,比如:

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

使用包含在Control_DF的数据,我想在我的主数据集,在那里我的体重乘以变量创建每个变量的新版本。所以,如果我的主要数据集是这样的:

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

然后,在开放代码,是我想要做的是这样的:

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

不过,我需要的不是硬编码这一种方式,并且使得被引用的变量的数量是任意的。

任何人都可以帮助我吗?

+0

有什么逻辑,如果你不想硬编码呢? – mtoto

+0

在我的例子中,我们有V1-V3,但在应用中,我可能有V1 - V10或V1 - V76等.dplyr的美丽是简洁易读的代码,但我很努力地将此延伸到问题。我可以做些什么或者什么,但是我认为效率会降低,而且它的可读性肯定会降低,这对我来说不太合适。 – TomFromWales

+0

如果我能以某种方式将“weighted_V1 = V1 * w1,...,weighted_Vn = Vn * wn”放入一个字符串中,然后“粘贴并执行”到变异函数中,那会很好! – TomFromWales

回答

0

lapplyMapcbind基地R你可以做如下:

# 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) 

输出:

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