【问题标题】:Transform ids -> items to {pairs of ids} -> items将 ids -> items 转换为 {pairs of ids} -> items
【发布时间】:2016-08-06 21:15:08
【问题描述】:

我有一个这样的data.frame:

x1 <- data.frame(id=1:3,item=c("A","B","A","B","C","D"))
x1[order(x1$item),]
  id item
1  1    A
3  3    A
2  2    B
4  1    B
5  2    C
6  3    D

我想得到:

id1=c(1,2,1,3,2,3)
id2 = c(2,1,3,1,3,2)
A=c(0,0,1,1,0,0)
B=c(1,1,0,0,0,0)
C = 0
D=0
datawanted <- data.frame(id1,id2,A,B,C,D)
  id1 id2 A B C D
1   1   2 0 1 0 0
2   2   1 0 1 0 0
3   1   3 1 0 0 0
4   3   1 1 0 0 0
5   2   3 0 0 0 0
6   3   2 0 0 0 0

如果 person1 和 person2 都有 B,那么在 datawanted 数据框中,A 列得到 1,否则得到 0。

有人可以给我一些R中的建议或功能来解决这个问题吗?

【问题讨论】:

  • id2的逻辑是什么?
  • id2 和 id1 一样,person1 和 person2 在 B 上有一个联系人,就这样吧。
  • datawanted的第5行和第6行的逻辑是什么?
  • person2 和 person3 没有联系,所以表示零

标签: r dataframe


【解决方案1】:

很酷的问题。你有一个二分图,所以关注Gabor's tutorial...

library(igraph)
g = graph_from_edgelist(as.matrix(x1))
V(g)$type = grepl("[A-Z]", V(g)$name)

对于OP想要的输出,首先我们可以提取关联矩阵:

gi = get.incidence(g)
#   A B C D
# 1 1 1 0 0
# 2 0 1 1 0
# 3 1 0 0 1

请注意(感谢@thelatemail),如果您不想使用 igraph,可以使用table(x1) 访问gi

然后,我们看一下id的组合:

res = t(combn(nrow(gi), 2, function(x) c(
    as.integer(rownames(gi)[x]), 
    pmin( gi[x[1], ], gi[x[2], ] ) 
)))

dimnames(res) <- list( NULL, c("id1", "id2", colnames(gi)))
#      id1 id2 A B C D
# [1,]   1   2 0 1 0 0
# [2,]   1   3 1 0 0 0
# [3,]   2   3 0 0 0 0

这本质上是 OP 想要的输出。它们包含了多余的行(例如,1,2 和 2,1)。


使用图表的有趣原因 (ht Chris):

V(g)$color <- ifelse(V(g)$type, "red", "light blue")
V(g)$x     <- (1:2)[ V(g)$type + 1 ]
V(g)$y     <- ave(seq_along(V(g)), V(g)$type, FUN = seq_along)
plot(g)

或者,显然这或多或少可以像

plot(g, layout = layout.bipartite(g)[,2:1])

【讨论】:

  • 第一部分不就是table(x1)吗?
  • @thelatemail 当然可以,但它是一个图表,所以不妨将它存储为一个。如果 OP 在此之后没有完成他们的分析,他们可能会利用 igraph 拥有的任何其他工具(......虽然我自己对它们并不熟悉)。好点,不过,我已经编辑以反映它。
  • 谢谢,如果id像c(1,3,4)这样变化,你给的方法可能会导致下标出站。 combn 和 pmin 确实给了我一些帮助。我需要考虑一下 id 是否没有与 rownumbers 相关联,它是如何工作的?
  • 我使用这样的代码,这会引起任何问题吗? res[,1] &lt;- x1$id[res[,1]]res[,2] &lt;- x1$id[res[,2]]
  • @chunjin 不错。是的,我认为你的方法有效。我还进行了编辑以显示上面的不同方式,将res 的构造更改为使用as.integer(rownames(gi)[x]) 而不是x
猜你喜欢
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 2013-01-09
  • 2019-04-19
  • 1970-01-01
  • 2023-03-08
  • 2020-12-18
  • 1970-01-01
相关资源
最近更新 更多