将数值向量中的值乘以数据框

时间:2016-06-28 12:42:18

标签: r

我有一个数字向量:

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

然后我有一个如下所示的数据框:

        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

我想将数字向量中的数字乘以此数据框中Nr列中的数字。当然,将值乘以名称很重要。这意味着数字向量中的Mark_1应乘以Nr = 60.1020,Mark_2相同,Stephen {3乘40.5880等等。

有人可以推荐任何简单的解决方案吗?

2 个答案:

答案 0 :(得分:2)

在仅提取match名称的第一部分后,您可以使用vec_exp来匹配名称,即从Mark等中提取Mark_1

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是NA,因为data.frame中没有匹配。

如果你想保留这些条目而不像以前那样匹配数据,你可以这样做:

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

这首先计算匹配,然后只在它们不是NA的情况下相乘。

答案 1 :(得分:2)

我们可以使用base R方法。使用vectordata.frame转换为stack,创建一个&#39;名称&#39;通过删除&#39; ind&#39;中的子字符串和merge与data.frame(&#39; df1&#39;)。然后,我们可以将&#39; Nr&#39;和价值观#39;列。

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

或者使用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