我正在使用一个包含情侣信息的数据集。由列ID1
中的唯一ID标识的夫妇中的人1与由列ID2
中的唯一标识标识的夫妇的人2形成夫妇。数据集如下所示:
stack <- cbind(ID1 = c(1, 2, 2, 3, 4, 4, 4, 5, 6),
ID2 = c(4, 3, 3, 2, 1, 1, 1, 6, 5),
what_I_want = c(1, 2, 2, 2, 1, 1, 1, 3, 3))
我想要的只是列举不同的情侣。你可以在what_I_want
栏中看到我的意思。这项任务并不容易,因为我有几行是关于同一对的(比如第1行、第5行、第6行和第7行都是关于相同的对,对编号为1(。除此之外,并不是所有的情侣都会有相同的排数(比如情侣1会出现在4排,情侣2会出现在3排等等(。这就是为什么我很难做到这一点。我考虑过循环和合并,但我不知道怎么做。任何帮助都将不胜感激<3
一个方便的选项是使用igraph
:
grp <- clusters(graph_from_data_frame(df[1:2]))$membership
df$what_I_want <- grp[match(df$ID1, names(grp))]
ID1 ID2 what_I_want
1 1 4 1
2 2 3 2
3 2 3 2
4 3 2 2
5 4 1 1
6 4 1 1
7 4 1 1
8 5 6 3
9 6 5 3
如果您的ID是数值,则可以使用dplyr
:
library(dplyr)
stack %>%
as.data.frame() %>%
mutate(small = pmin(ID1, ID2),
large = pmax(ID1, ID2)) %>%
group_by(small, large) %>%
mutate(number = cur_group_id()) %>%
ungroup() %>%
select(-small, -large)
返回
# A tibble: 9 x 4
ID1 ID2 what_I_want number
<dbl> <dbl> <dbl> <int>
1 1 4 1 1
2 2 3 2 2
3 2 3 2 2
4 3 2 2 2
5 4 1 1 1
6 4 1 1 1
7 4 1 1 1
8 5 6 3 3
9 6 5 3 3
首先,我们按大小对ID进行排序,因此(1,4)
和(4,1)
都被转换为(1,4)
。最后,我们使用这些排序的id作为分组变量,并添加一个组id。
这里有一个基本的R选项-
vec <- with(df, paste(pmin(ID1, ID2), pmax(ID1, ID2)))
df$result <- match(vec, unique(vec))
df
# ID1 ID2 result
#1 1 4 1
#2 2 3 2
#3 2 3 2
#4 3 2 2
#5 4 1 1
#6 4 1 1
#7 4 1 1
#8 5 6 3
#9 6 5 3
具有igraph
+stack
+merge
的选项
merge(df,
stack(
membership(
components(
graph_from_data_frame(df)
)
)
),
by.x = "ID1",
by.y = "ind",
all.x = TRUE
)
它给出
ID1 ID2 values
1 1 4 1
2 2 3 2
3 2 3 2
4 3 2 2
5 4 1 1
6 4 1 1
7 4 1 1
8 5 6 3
9 6 5 3