简体   繁体   English

将数值向量中的值乘以数据帧中的特定值

[英]Multiply values from numeric vector by specific values from data frame

I have a numeric vector: 我有一个数值向量:

> dput(vec_exp)
structure(c(12.344902729712, 6.54357482855349, 17.1939193108764, 
            23.1029632631654, 8.91495023159554, 14.3259091357051, 18.0494234749187, 
            2.92524638658168, 5.10306474037357, 2.66645609602021), .Names = c("Arthur_1", 
                                                                              "Mark_1", "Mark_2", "Mark_3", "Stephen_1", "Stephen_2", 
                                                                              "Stephen_3", "Rafael_1", "Marcus_1", "Georg_1"))

and then I have a data frame like the one below: 然后我有一个数据框,如下所示:

        Name     Nr       Numb
1  Rafael      20.8337  20833.7
2  Joseph      25.1682  25168.2
3  Stephen     40.5880  40588.0
4  Leon       198.7730 198773.0
5  Thierry     16.5430  16543.0
6  Marcus      31.6600  31660.0
7  Lucas       39.6700  39670.0
8  Georg      194.9410 194941.0
9  Mark        60.1020  60102.0
10 Chris       56.0578  56057.8

I would like to multiply the numbers in numeric vector by the numbers from the column Nr in this data frame. 我想将数值向量中的数字乘以该数据帧中Nr列的数字。 Of course it is important to multiply the values by the name. 当然,将值乘以名称很重要。 It means that Mark_1 from numeric vector should be multiplied by the Nr = 60.1020 , same for Mark_2, and Stephen_3 by 40.5880 , etc. 这意味着数字向量中的Mark_1应该乘以Nr = 60.1020 ,与Mark_2相同,而Stephen_3应乘以40.5880,依此40.5880

Can someone recommend any easy solution ? 有人可以推荐任何简单的解决方案吗?

You could use match to match the names after extracting only the first part of the names of vec_exp , ie extract Mark from Mark_1 etc. 您可以在仅提取vec_exp名称的第一部分后使用match来匹配名称,即从Mark_1等中提取Mark

vec_exp * df$Nr[match(sub("^([^_]+).*", "\\1", names(vec_exp)), df$Name)]
# Arthur_1     Mark_1     Mark_2     Mark_3  Stephen_1  Stephen_2  Stephen_3   Rafael_1   Marcus_1    Georg_1 
#       NA  393.28193 1033.38894 1388.53430  361.84000  581.46000  732.59000   60.94371  161.56303  519.80162 

Arthur is NA because there's no match in the data.frame. Arthur是NA因为data.frame中没有匹配项。


If you want to keep those entries without a match in the data as they were before, you could do it like this: 如果您想保留这些条目而不像以前那样在数据中进行匹配,则可以这样操作:

i <- match(sub("^([^_]+).*", "\\1", names(vec_exp)), df$Name)
vec_exp[!is.na(i)] <- vec_exp[!is.na(i)] * df$Nr[na.omit(i)]

This first computes the matches and then only multiplies those if they are not NA. 这将首先计算匹配项,然后仅在它们不是NA时才将它们相乘。

We can use base R methods. 我们可以使用base R方法。 Convert the vector to a data.frame with stack , create a 'Name' column by removing the substring from 'ind' and merge with the data.frame ('df1'). vector转换为带有stackdata.frame ,通过从'ind'中删除子字符串来创建'Name'列,然后与data.frame('df1') merge Then, we can multiply the 'Nr' and the 'values' column. 然后,我们可以将“ Nr”和“ values”列相乘。

d1 <- merge(df1, transform(stack(vec_exp), Name = sub("_.*", "", ind)), all.y=TRUE)
d1$Nr*d1$values

Or with dplyr , it is much more easier to understand. 或使用dplyr ,它更容易理解。

library(dplyr)
library(tidyr)
stack(vec_exp) %>%
        separate(ind, into = c("Name", "ind")) %>%
        left_join(., df1, by = "Name") %>% 
         mutate(res = values*Nr) %>% 
        .$res
#[1]         NA  393.28193 1033.38894 1388.53430  361.84000  
#[6]    581.46000  732.59000   60.94371  161.56303  519.80162

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM