如何解决R使用combin与apply
我有一个数据框,其中包含许多变量和观察值的百分比值,如下所示:
obs <- data.frame(Site = c("A","B","C"),X = c(11,22,33),Y = c(44,55,66),Z = c(77,88,99))
我需要将此数据准备为网络分析的边缘列表,以“站点”作为节点,其余变量作为边缘。结果应如下所示:
Node1 Node2 Weight Type
A B 33 X
A C 44 X
...
B C 187 Z
因此,对于“ Weight”,我们要计算所有可能的对的总和,并分别针对每一列(以“ Type”结尾)进行计算。
我想答案是必须在apply
表达式上使用combn
,就像这里的Applying combn() function to data frame一样,但是我还不能完全解决。
我可以手工完成“网站”的组合
sites <- combn(obs$Site,2)
然后像这样的各个列
combA <- combn(obs$A,2,function(x) sum(x)
并将这些数据集绑定在一起,但这显然很快变得很烦人。
我试图一次完成所有变量列
b <- apply(newdf[,-1],1,function(x){
sum(utils::combn(x,2))
}
)
但是这有点问题。 有人可以帮忙吗?
解决方法
一种选择是创建一个函数,然后map
将该函数应用于您拥有的所有列。
func1 <- function(var){
obs %>%
transmute(Node1 = combn(Site,2)[1,],Node2 = combn(Site,2)[2,Weight = combn(!!sym(var),2,function(x) sum(x)),Type = var)
}
map(colnames(obs)[-1],func1) %>% bind_rows()
,
以下是使用combn
do.call(
rbind,combn(1:nrow(obs),FUN = function(k) cbind(data.frame(t(obs[k,1])),stack(data.frame(as.list(colSums(obs[k,-1]))))),simplify = FALSE
)
)
给出
X1 X2 values ind
1 A B 33 X
2 A B 99 Y
3 A B 165 Z
4 A C 44 X
5 A C 110 Y
6 A C 176 Z
7 B C 55 X
8 B C 121 Y
9 B C 187 Z
,
尝试一下
library(tidyverse)
obs_long <- obs %>% pivot_longer(-Site,names_to = "type")
sites <- combn(obs$Site,2) %>% t() %>% as_tibble()
Type <- tibble(type = c("X","Y","Z"))
merge(sites,Type) %>%
left_join(obs_long,by = c("V1" = "Site","type" = "type")) %>%
left_join(obs_long,by = c("V2" = "Site","type" = "type")) %>%
mutate(res = value.x + value.y) %>%
select(-c(value.x,value.y))
V1 V2 type res
1 A B X 33
2 A C X 44
3 B C X 55
4 A B Y 99
5 A C Y 110
6 B C Y 121
7 A B Z 165
8 A C Z 176
9 B C Z 187
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。