首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R使用combn和apply

R使用combn和apply
EN

Stack Overflow用户
提问于 2020-09-04 21:27:26
回答 3查看 153关注 0票数 2

我有一个数据框,其中包含许多变量和观测值的百分比值,如下所示:

代码语言:javascript
复制
obs <- data.frame(Site = c("A", "B", "C"), X = c(11, 22, 33), Y = c(44, 55, 66), Z = c(77, 88, 99))

我需要将此数据准备为网络分析的边缘列表,其中"Site“为节点,其余变量为边缘。结果应该如下所示:

代码语言:javascript
复制
Node1    Node2    Weight  Type
A         B         33     X
A         C         44     X
...
B         C         187    Z       

因此,对于“权重”,我们计算所有可能的对的总和,并分别计算每一列的总和(以“Type”结尾)。

我想解决这个问题的方法应该是在combn表达式上使用apply,比如这里的Applying combn() function to data frame,但是我还没有完全解决这个问题。

我可以通过手工获取"Site“的组合来完成这一切。

代码语言:javascript
复制
sites <- combn(obs$Site, 2)

然后,单个列如下所示

代码语言:javascript
复制
combA <- combn(obs$A, 2, function(x) sum(x)

并将这些数据集绑定在一起,但这显然很快就会变得令人讨厌。

我试着一次完成所有变量列,如下所示

代码语言:javascript
复制
b <- apply(newdf[, -1], 1, function(x){
sum(utils::combn(x, 2))
}
)

但这是有问题的。有人能帮帮忙吗?

EN

回答 3

Stack Overflow用户

发布于 2020-09-04 22:01:31

一种选择是创建一个函数,然后将该函数map到您拥有的所有列。

代码语言:javascript
复制
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()
票数 2
EN

Stack Overflow用户

发布于 2020-09-04 22:05:19

下面是一个使用combn的示例

代码语言:javascript
复制
do.call(
  rbind,
  combn(1:nrow(obs),
    2,
    FUN = function(k) cbind(data.frame(t(obs[k, 1])), stack(data.frame(as.list(colSums(obs[k, -1]))))),
    simplify = FALSE
  )
)

这给了我们

代码语言:javascript
复制
  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
票数 2
EN

Stack Overflow用户

发布于 2020-09-04 22:07:23

这样试试吧。

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63742144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档