我有类似下面的数据,表示实体之间的交互。
> library(tidyverse)
> set.seed(20)
> dta <- data_frame(group=c(1,1,2,2,2,3,3,3),
flag=c(1,0,1,0,0,0,1,1),
name=c('a','b','a','c','d','b','c','c'),
amount=rnorm(8,20))
# A tibble: 8 x 4
group flag name amount
<dbl> <dbl> <chr> <dbl>
1 1 1 a 21.2
2 1 0 b 19.4
3 2 1 a 21.8
4 2 1 c 18.7
5 2 0 d 19.6
6 3 0 b 20.6
7 3 1 c 17.1
8 3 1 c 19.1
可能存在一对一关系,一个实体发送给许多其他实体,或者许多实体从一个实体接收。 “组”列表示交互,而标志表示发送/接收(与发生的情况无关)。
对于网络分析,我需要group_by
组列,然后创建一个名为“ to”的列,该列包含组中行的“名称”值,其中标志是唯一的1或在其组中为0。在一对一交互的情况下,我用flag == 1
从行中分配名称。
我想要这样的东西:
dta %>%
group_by(group) %>%
mutate(to = case_when(sum(.$flag) == 1 ~ .$name[.$flag == 1],
sum(.$flag == 0) == 1 ~ .$name[.$flag == 0],
TRUE ~ .$name[.$flag == 1]))
group flag name amount to
<dbl> <dbl> <chr> <dbl> <chr>
1 1 1 a 21.2 a
2 1 0 b 19.4 a
3 2 1 a 21.8 d
4 2 1 c 18.7 d
5 2 0 d 19.6 d
6 3 0 b 20.6 b
7 3 1 c 17.1 b
8 3 1 c 19.1 b
mutate
使用.$
指的是整个tbl
而不是组。我确定可以使用do
来完成此操作,但是我对它的用法不是很熟悉,当我用上面的mutate调用替换它时,它给了我不想要的结构。
谢谢!
答案 0 :(得分:0)
我们可以创建一个频次列
library(dplyr)
dta %>%
group_by(group, flag) %>%
mutate(n = n()) %>%
group_by(group) %>%
mutate(to = name[which(n ==1)[1]]) %>%
select(-n)
# A tibble: 8 x 5
# Groups: group [3]
# group flag name amount to
# <dbl> <dbl> <chr> <dbl> <chr>
#1 1 1 a 21.2 a
#2 1 0 b 19.4 a
#3 2 1 a 21.8 d
#4 2 1 c 18.7 d
#5 2 0 d 19.6 d
#6 3 0 b 20.6 b
#7 3 1 c 17.1 b
#8 3 1 c 19.1 b
或者代替使用“ {group”和“ flag”分组,而是应用table
来获取“ flag”的频率并提取与频率1对应的name
dta %>%
group_by(group) %>%
mutate(to = name[which(table(factor(flag,
levels = 0:1))[as.character(flag)] == 1)])