[英]Create matrix based upon group membership
我想創建一個矩陣,指示來自 dataframe 的組成員身份。 例如,一個 NxN 矩陣,其中 1 表示一個社區與另一個社區在同一個城市內,0 表示這些社區屬於不同城市的一部分。 例如:
hoodid <- c(1:10)
cityid <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3)
df <- data.frame(hoodid, cityid)
df
# hoodid cityid
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 3
# 8 8 3
# 9 9 3
# 10 10 3
期望的結果是:
# 0 1 1 0 0 0 0 0 0 0
# 1 0 1 0 0 0 0 0 0 0
# 1 1 0 0 0 0 0 0 0 0
# 0 0 0 0 1 0 0 0 0 0
# 0 0 0 1 0 0 0 0 0 0
# 0 0 0 0 0 0 1 1 1 1
# 0 0 0 0 0 1 0 1 1 1
# 0 0 0 0 0 1 1 0 1 1
# 0 0 0 0 0 1 1 1 0 1
# 0 0 0 0 0 1 1 1 1 0
這有效:
library(Matrix)
m = do.call(bdiag, lapply(
lengths(split(df$cityid, df$cityid)),
function(n) 1 - diag(n)
))
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . 1 1 . . . . . . .
# [2,] 1 . 1 . . . . . . .
# [3,] 1 1 . . . . . . . .
# [4,] . . . . 1 . . . . .
# [5,] . . . 1 . . . . . .
# [6,] . . . . . . 1 1 1 1
# [7,] . . . . . 1 . 1 1 1
# [8,] . . . . . 1 1 . 1 1
# [9,] . . . . . 1 1 1 . 1
# [10,] . . . . . 1 1 1 1 .
這假定您的數據首先按cityid
排序,並且沒有重復或任何其他奇怪的內容。
如果你想要一個香草矩陣,你可以as.matrix(m)
。
我有一個類似的問題。 Frank 的解決方案對我有用,但我想提出一個更通用的解決方案。 Frank 的解決方案需要訂購組成員。 此外,如果您創建一個非常大的矩陣(如我所做的那樣),請在lapply
中留下大量緩存,這些緩存無法通過垃圾收集( gc()
)進行清理。
所需軟件包: igraph
和data.table
(不是必需的,但它更快)。
library(igraph)
library(Matrix)
library(data.table)
hoodid <- c(1:10)
cityid <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3)
df <- data.frame(hoodid, cityid)
df
# hoodid cityid
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 3
# 8 8 3
# 9 9 3
# 10 10 3
city_list = unique(df$cityid)
edges = list()
for (i in 1:length(city_list)) {
edges[[i]] = data.table(t(combn(df[df$cityid == city_list[i], 'hoodid'], 2)))
}
edges = rbindlist(edges)
g = graph_from_edgelist(as.matrix(edges), directed = F)
g = get.adjacency(g)
g
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . 1 1 . . . . . . .
# [2,] 1 . 1 . . . . . . .
# [3,] 1 1 . . . . . . . .
# [4,] . . . . 1 . . . . .
# [5,] . . . 1 . . . . . .
# [6,] . . . . . . 1 1 1 1
# [7,] . . . . . 1 . 1 1 1
# [8,] . . . . . 1 1 . 1 1
# [9,] . . . . . 1 1 1 . 1
# [10,] . . . . . 1 1 1 1 .
不帶 data.table
library(igraph)
library(Matrix)
hoodid <- c(1:10)
cityid <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3)
df <- data.frame(hoodid, cityid)
df
# hoodid cityid
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 3
# 8 8 3
# 9 9 3
# 10 10 3
edges = data.frame(matrix(ncol = 2, nrow = 0))
for (i in unique(df$cityid)) {
edges = rbind(edges, t(combn(df[df$cityid == i, 'hoodid'], 2)))
}
g = graph_from_edgelist(as.matrix(edges), directed = F)
g = get.adjacency(g)
g
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . 1 1 . . . . . . .
# [2,] 1 . 1 . . . . . . .
# [3,] 1 1 . . . . . . . .
# [4,] . . . . 1 . . . . .
# [5,] . . . 1 . . . . . .
# [6,] . . . . . . 1 1 1 1
# [7,] . . . . . 1 . 1 1 1
# [8,] . . . . . 1 1 . 1 1
# [9,] . . . . . 1 1 1 . 1
# [10,] . . . . . 1 1 1 1 .
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.