2

我有两个数据框:

df1 <- data.frame(Values=c(0.01,0.05), row.names=c("X", "Y"))
df1
  Values
X   0.01
Y   0.05

df2 <-data.frame(c(0,1,1), c(1,0,0), c(1,1,1))
colnames(df2) <- c("X","Y","Z")

df2
  X Y Z
1 0 1 1
2 1 0 1
3 1 0 1

我希望对 df2 执行逐行操作,将 df2 中的每一与 df1 中的相应行相乘,然后执行求和

例如,对于 df2 的第 1 行,我希望计算:

df2 %>% rowwise %>% mutate(newVAL=(df1["X",]*df2[1,"X"])+(df1["Y",]*df2[1,"Y"]))

同时排除不匹配的列(df1 中的行)或具有 NA。

我在 df1 中有数千行,在 df2 中有数千行和列。

任何帮助深表感谢!!

PS。我已经在 Perl 中使用哈希实现了这一点,并使用 system() 调用在 Rmarkdown 文档中执行这些计算。为了让它完全可重现,我正在尝试在 R 中重做它。如有必要,很高兴分享 Perl 代码。

谢谢。

4

3 回答 3

3

如果我理解正确,看起来您需要sweep.

df3 <- sweep(df2[, rownames(df1)], 2, t(df1), '*')
df3$total <- rowSums(df3)
于 2017-01-17T23:05:21.197 回答
3

这是在基本 R 中尝试将行与两组之间的列进行匹配:

rowSums(
  sweep(df2,
        MARGIN=2,
        STATS=df1$Values[match(colnames(df2), rownames(df1))],
        FUN=`*`),
  na.rm=TRUE
)
#[1] 0.05 0.01 0.01
于 2017-01-17T23:05:34.770 回答
1

我们也可以使用rep相同的长度相乘,然后得到rowSums. 使用起来会更高效,rep因为它更快

rowSums(df2[rownames(df1)] * rep(df1$Values, each = nrow(df2)))
#[1] 0.05 0.01 0.01

或者使用tidyrverse

library(dplyr)
library(purrr)
df2 %>% 
     select_(.dots = rownames(df1)) %>% 
     map2(df1$Values, `*`) %>%
     reduce(`+`)
#[1] 0.05 0.01 0.01

更新

如果我们需要它作为一个列,

df2 %>% 
    select_(.dots = rownames(df1)) %>%
    map2(df1$Values, `*`) %>%
    reduce(`+`) %>%
    mutate(df2, total = .)
#  X Y Z total
#1 0 1 1  0.05
#2 1 0 1  0.01
#3 1 0 1  0.01
于 2017-01-18T03:24:47.370 回答