![](/img/trans.png)
[英]Finding the minimum distances/levels between nodes in a graph like dataframe in R
[英]dataframe query in R nodes graph
我有數據框
df<-data.frame(source=c("a","a","a",'z1','b'),target=c("b","c","d",'a','e'),wsource=c('w1','w2','w1','w2','w1'),wtarget=c('w1','w1','w1','w1','w2'))
source target wsource wtarget
a b w1 w1
a c w1 w1
a d w1 w1
z1 a w2 w1
b e w1 w2
它代表一個圖形( source
和target
是節點ID,而wsource
和wtarget
是標簽)。 如果節點在源列中,我想為每個不同的節點獲取與wtarget關聯的次數,如果節點在目標列中為n,則與wsource關聯的次數。
我正在尋找的數據幀是:
node w1 w2
a 3 1
b 1 1
c 1 0
d 1 0
e 1 0
z1 1 0
例如,請注意,節點a
從它作為源出現的三倍中在w1
列中獲得其3(查看其對應的wtarget),並從它作為目標出現的第四行中獲得其在w2
列中的1(查看其對應的wsource)。 )。
我嘗試首先對列進行排序,但是在我的應用程序中,節點ID是長整數。 即使對它們進行排序,也不能保證節點僅會出現在一列(源或目標)中。
我想知道一種處理此查詢的方法。
取消列出並列出:
將source--target
與wtarget--wsource
以便將所有節點放在一列中,所有標簽放在另一列中,並使用table
生成結果:
table(
unlist(df[c("source","target")]),
unlist(df[c("wtarget","wsource")])
)
# w1 w2
# a 3 1
# b 1 1
# c 0 1
# d 1 0
# e 1 0
# z1 1 0
獲取完整的節點列表:
sources<-unique(df$source)
targets<-unique(df$target)
st<-unique(c(sources,targets))
為for
循環設置變量:
node<-NULL
w1<-NULL
w2<-NULL
創建列:
for(i in 1:length(st)) {
node[i]<-st[i]
w1[i]<-sum(df$wtarget[df$source==st[i]]==1, df$wsource[df$target==st[i]]==1)
w2[i]<-sum(df$wtarget[df$source==st[i]]==2, df$wsource[df$target==st[i]]==2)
}
將所有內容與cbind結合在一起:
cbind(node,w1,w2)
結果:
node w1 w2
[1,] "a" "3" "1"
[2,] "z1" "1" "0"
[3,] "b" "1" "1"
[4,] "c" "0" "1"
[5,] "d" "1" "0"
[6,] "e" "1" "0"
如果要訂購此命令,可以添加以下行:
nodelist<-cbind(node,w1,w2)
nodelist<-nodelist[order(nodelist[,1]),]
node w1 w2
[1,] "a" "3" "1"
[2,] "b" "1" "1"
[3,] "c" "0" "1"
[4,] "d" "1" "0"
[5,] "e" "1" "0"
[6,] "z1" "1" "0"
更新:這是多個w的通用版本:
sources<-unique(df$source)
targets<-unique(df$target)
st<-unique(c(sources,targets))
node<-NULL
nodes<-NULL
w<-NULL
for(t in 1:max(c(df$wsource,df$wtarget))) {
for(i in 1:length(st)) {
node[i]<-st[i]
w[i]<-sum(df$wtarget[df$source==st[i]]==t, df$wsource[df$target==st[i]]==t)
}
nodes<-cbind(nodes,w)
}
nodelist<-data.frame(cbind(node,nodes))
nodelist<-nodelist[order(nodelist[,1]),]
您需要做一點點的工作來修復列名,但這並不難。
您可以使用
library(dplyr)
library(tidyr)
df <- data.frame(source=c("a","a","a",'z1','b'),target=c("b","c","d",'a','e'),wsource=c(1,2,1,2,1),wtarget=c(1,1,1,1,2), stringsAsFactors = FALSE)
df <- rbind(as.matrix(df[, c(1, 4)]), as.matrix(df[, c(2, 3)]))
df <- df %>% data.frame %>% group_by(source, wtarget) %>% summarise(n = n()) %>%
spread(wtarget, n) %>% mutate(`1` = ifelse(is.na(`1`), 0, `1`), `2` = ifelse(is.na(`2`), 0, `2`))
apply(df, 2, function(x) ifelse(is.na(x), 0, x))
# A tibble: 6 x 3
# Groups: source [6]
source `1` `2`
<fctr> <dbl> <dbl>
1 a 3.00 1.00
2 b 1.00 1.00
3 c 0 1.00
4 d 1.00 0
5 e 1.00 0
6 z1 1.00 0
我希望這有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.