我需要将数据帧中的值(基于特定分组)乘以一个单独的矩阵,该矩阵对这些值施加某种权重。乘法是我编写的函数的一部分。我知道如何以最基本的方式做到这一点。但我无法理解如何在更现实的设置中做到这一点。我希望我的例子能清楚地说明这个问题。
我有以下示例数据集:
set.seed(45)
tibble(site = rep(c(LETTERS[1:3]), each = 6),
name = rep(c(letters[10:15]), 3),
size = runif(18)) %>%
arrange(site, name) -> d_tibble
我还有一个矩阵,可以表示某种权重:
d_matrix <- matrix(0, 6, 6)
diag(d_matrix) <- 1
rownames(d_matrix) <- letters[10:15]
colnames(d_matrix) <- letters[10:15]
d_matrix
## j k l m n o
## j 1 0 0 0 0 0
## k 0 1 0 0 0 0
## l 0 0 1 0 0 0
## m 0 0 0 1 0 0
## n 0 0 0 0 1 0
## o 0 0 0 0 0 1
我还有一个函数,应该将向量p
乘以矩阵b
test_fct <- function(a, b) {
p <- a / sum(a)
sum(p * (p %*% b))
}
然后我想做类似这样的事情,即在中使用我的函数来总结()
:
#d_tibble %>%
# group_by(site) %>%
# summarise(y = test_fct(size, b))
但是我不知道如何将b
,即矩阵,放入我的自定义函数中,以便它的列名在按site
分组时与name
变量匹配。
我尝试的一种方法是将矩阵合并到数据帧中-这样我就可以在一个数据帧中包含所有内容:
d_tibble %>%
left_join(d_matrix %>%
as_tibble() %>%
mutate(name = colnames(d_matrix))) -> tibble_matrix_join
但我需要在给定site
分组的情况下以某种方式访问name
变量的唯一值,以便在我的函数test_fct()
中为向量/矩阵乘法选择正确的列(j, k,l,m,n,o):
#tibble_matrix_join %>%
# group_by(site) %>%
# summarise(result = test_fct(size, b))
我试图检查一般设置是否有效,即仅适用于一个站点,并将所有名称包含在矩阵中,它确实:
d_tibble %>%
filter(site == "A") %>%
pull(size) -> my_x
test_fct(my_x, d_matrix)
## [1] 0.1858158
my_p <- my_x/sum(my_x)
sum(my_p * (my_p %*% d_matrix))
## [1] 0.1858158
在这个例子中,d_matrix中的所有列都可以在tibble的'name'列中找到。如果不是这样,我们可以这样做
library(dplyr)
d_tibble %>%
group_by(site) %>%
summarise(out = test_fct(size, d_matrix[intersect(row.names(d_matrix),
name), intersect(colnames(d_matrix),
name), drop = FALSE]), .groups = "drop")
-输出
# A tibble: 3 × 2
site out
<chr> <dbl>
1 A 0.186
2 B 0.264
3 C 0.218
-测试较小的数据
d_tibble %>%
slice_sample(n = 12) %>%
arrange(site, name) %>%
group_by(site) %>%
summarise(out = test_fct(size, d_matrix[intersect(row.names(d_matrix),
name), intersect(colnames(d_matrix),
name), drop = FALSE]), .groups = "drop")
-输出
# A tibble: 3 × 2
site out
<chr> <dbl>
1 A 0.227
2 B 0.416
3 C 0.481