将一个数据框中的行(带有行名)与另一个数据框中的匹配列名相乘
Multiply rows (with row names) in one data frame with matching column names in another
我有两个数据框:
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 执行 rowwise 操作,我将 df2 中的每个 column 与其对应的 相乘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 代码。
谢谢。
如果我没理解错的话,你好像需要sweep
.
df3 <- sweep(df2[, rownames(df1)], 2, t(df1), '*')
df3$total <- rowSums(df3)
这是在 base 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
我们也可以用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
我有两个数据框:
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 执行 rowwise 操作,我将 df2 中的每个 column 与其对应的 相乘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 代码。
谢谢。
如果我没理解错的话,你好像需要sweep
.
df3 <- sweep(df2[, rownames(df1)], 2, t(df1), '*')
df3$total <- rowSums(df3)
这是在 base 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
我们也可以用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