我正在觀察用戶可以長大或摺疊的d3js樹的變化。對樹的更新由閃亮的ui作爲扁平json返回到服務器(r)並映射到數據幀。刪除R中沒有兒童的兄弟姐妹
我想找到沒有在所有的兒童,或僅兄弟姐妹兄弟姐妹有孩子和修剪他們
這裏有這樣一個數據幀
x=data.frame(cyl=c(4,4,4,6,6,8),vs=c(0,1,1,0,1,NA),am=c(NA,0,1,rep(NA,3)))
的例子。在此例如我想從這個樹在ggplot/8的下方,以修剪和ggplot/4/0
我正在觀察用戶可以長大或摺疊的d3js樹的變化。對樹的更新由閃亮的ui作爲扁平json返回到服務器(r)並映射到數據幀。刪除R中沒有兒童的兄弟姐妹
我想找到沒有在所有的兒童,或僅兄弟姐妹兄弟姐妹有孩子和修剪他們
這裏有這樣一個數據幀
x=data.frame(cyl=c(4,4,4,6,6,8),vs=c(0,1,1,0,1,NA),am=c(NA,0,1,rep(NA,3)))
的例子。在此例如我想從這個樹在ggplot/8的下方,以修剪和ggplot/4/0
首先,您需要以更高效的方式表示您的樹。您當前的表示(每行似乎代表樹中的一個分支)使其很難處理。一個更好的表示將是 - 每個節點的一行,並帶有一個node_id(見下文)。你爲整棵樹建立這張桌子。您爲「可見性」添加矢量/列,然後每次在節點上展開/摺疊時都不需要重新創建/過濾數據集(稍後解釋)。所以你定樹的基本表示會看起來像:
tree = data.frame(
node_id = 1:10,
node_data = c("ggplot",4,6,8,0,1,0,1,0,1),
parent_id = c(NA,1,1,1,2,2,3,3,6,6),
visible = rep(T,10)
)
現在,真的有一棵樹往往是創建一個asjacency矩陣有益的工作。所以如果你有N個節點(在我們的例子中是10),那麼你得到一個N * N的二進制矩陣,其中A(i,j)= 1,如果i是j的父親。你可以從上面使用下面的代碼創建鄰接矩陣:
A = matrix(0,nrow = nrow(tree),ncol=nrow(tree))
A[cbind(tree$parent_id,tree$node_id)] = 1
現在,你真正需要的是一個「decendency矩陣」,一個矩陣B,其中B(I,J)= 1當且僅當j是我的一個派生人。你可以通過將A乘以自身(矩陣乘法)並且將A的冪加起來,如果對於樹A ^(d + 1)= 0有d個級別,所以不需要超出那個。所以:
B = A + A%*%A + A%*%A%*%A #that should be enough here, more generally you'd need some looping to add enough powers of A
B0 = 0+ (B>0)
現在。修剪樹的節點i,你需要以下條件:
prune_at = function(node_id,decenedency,current_visibility) {
to_prune = which(decendency[node_id,]>0)
new_visibility = current_visibility
new_visibility[to_prune] = F
new_visibility
}
# for example:
pruned = prune_at(2,B0,tree$visibility)
要展開可見節點,這樣你會看到它的孩子:
expand_at = function(node_id,adjacency,current_visibility) {
new_visibility = current_visibility
if(current_visibility[node_id]==T) {
to_expand = which(adjacency[node_id,]==1)
new_visibility[to_expand] = T
}
new_visibility
}
#example
expand_at(2,A,pruned)
所以,在所有的 - 你創建這些曾經代表對於整個數據集。那麼所有你需要的就是使用「可見性」向量,從一個操作轉換到另一個操作,說明哪些節點可見。
我希望它是有道理的。
你想修剪哪裏?這是關於R還是關於D3.js? – altocumulus
這是一個問題。我想過濾一個基於樹特性的數據幀 – yonicd
好的。我刪除了d3標籤,因爲標籤應該表明問題的內容,而不是周圍的內容。 – altocumulus