为无序对生成唯一的对偶标识符

时间:2019-08-12 08:21:14

标签: r dplyr unique pairwise

我正在处理的数据帧以二进位格式编码,其中每个观察值(即行)都包含源节点(from)和目标节点(to)以及其他一些二元协变量(例如,二元相关,corr)。

为简单起见,我想将每个二元组视为无序的,并为每个二元组生成一个唯一的标识符,例如elow(df1):

# original data
df <- data.frame(
from = c("A", "A", "A", "B", "C", "A", "D", "E", "F", "B"),
to = c("B", "C", "D", "C", "B", "B", "A", "A", "A", "A"),
corr = c(0.5, 0.7, 0.2, 0.15, 0.15, 0.5, 0.2, 0.45, 0.54, 0.5))

   from to corr
1     A  B 0.50
2     A  C 0.70
3     A  D 0.20
4     B  C 0.15
5     C  B 0.15
6     A  B 0.50
7     D  A 0.20
8     E  A 0.45
9     F  A 0.54
10    B  A 0.50

# desired format
df1 <- data.frame(
from = c("A", "A", "A", "B", "C", "A", "D", "E", "F", "B"),
to = c("B", "C", "D", "C", "B", "B", "A", "A", "A", "A"),
corr = c(0.5, 0.7, 0.2, 0.15, 0.15, 0.5, 0.2, 0.45, 0.54, 0.5),
dyad = c(1, 2, 3, 4, 4, 1, 3, 5, 6, 1))

   from to corr dyad
1     A  B 0.50    1
2     A  C 0.70    2
3     A  D 0.20    3
4     B  C 0.15    4
5     C  B 0.15    4
6     A  B 0.50    1
7     D  A 0.20    3
8     E  A 0.45    5
9     F  A 0.54    6
10    B  A 0.50    1

其中,成对的A-B / B-A,A-D / D-A被视为相同的对,并分配有相同的成对标识符。 从原始数据中提取无序对的列表很容易,但是很难将它们映射到原始数据帧以生成无序的对偶标识符。有人可以对此提供一些见解吗?

2 个答案:

答案 0 :(得分:2)

一个dplyr选项可能是:

df %>%
 mutate(dyad = group_indices(., paste0(pmax(from, to), pmin(from, to))))

   from to corr dyad
1     A  B 0.50    1
2     A  C 0.70    2
3     A  D 0.20    4
4     B  C 0.15    3
5     C  B 0.15    3
6     A  B 0.50    1
7     D  A 0.20    4
8     E  A 0.45    5
9     F  A 0.54    6
10    B  A 0.50    1

或者:

df %>%
 mutate(dyad = dense_rank(paste0(pmax(from, to), pmin(from, to))))

但是,如果您需要按特定顺序分配标识符(这意味着标识符本身拥有一些信息),那么@Ronak Shah的解决方案可能对您更好。

答案 1 :(得分:1)

使用apply的一种方法是将sortpaste的值分成两列,将它们转换为factor,然后转换为integer以获取唯一值每个组合的编号。

df$temp <- apply(df[1:2], 1, function(x) paste(sort(x), collapse = "_"))
df$dyad <- as.integer(factor(df$temp, levels = unique(df$temp)))
df$temp <- NULL
df

#   from to corr dyad
#1     A  B 0.50    1
#2     A  C 0.70    2
#3     A  D 0.20    3
#4     B  C 0.15    4
#5     C  B 0.15    4
#6     A  B 0.50    1
#7     D  A 0.20    3
#8     E  A 0.45    5
#9     F  A 0.54    6
#10    B  A 0.50    1