2016-10-12 25 views
3

我是一個新的S4類,並四處尋找解決方案,但失敗:( 我有一個S4類列表,不知道它是否是嵌套列表,但我想要將其更改爲數據框。我的表看起來是稱爲z,S4類列表到數據框

head(z) 
[[1]] 
An object of class "AgNode" 
Slot "center": 
x: 1515, y: 2258 

Slot "name": 
[1] "hsa:4052" 

Slot "txtLabel": 
An object of class "AgTextLabel" 
Slot "labelText": 
[1] "hsa:4052" 

Slot "labelLoc": 
x: 0, y: 0 

Slot "labelJust": 
[1] "n" 

Slot "labelWidth": 
[1] 50 

[[2]] 
An object of class "AgNode" 
Slot "center": 
x: 1443, y: 2567 

Slot "name": 
[1] "hsa:1311" 

Slot "txtLabel": 
An object of class "AgTextLabel" 

等等,我想提取從名稱插槽上的中心插槽和名稱的X和Y值,並把三個在數據幀。我怎麼能做到這一點?

see<-do.call(cbind, lapply(z, stack)) 

我試過,但它給出了一個錯誤

Error in as.list.default(x) : 
no method for coercing this S4 class to a vector 

任何人都可以幫我嗎?

回答

4

如果你想要一個「一行代碼」:

purrr::map_df(x, ~as.list(set_names(getPoints(getNodeCenter(.)), c("x", "y"))))` 

但我喜歡拼寫這些了,如果有,因爲最終我們要編程的人沒有性能損失:

library(Rgraphviz) 
library(purrr) 

V <- letters[1:10] 
M <- 1 
g1 <- randomGraph(V, M, .2) 
z <- agopen(g1,name="foo") 
x <- AgNode(z) 

map(x, getNodeCenter) %>% 
    map(getPoints) %>% 
    map(set_names, c("x", "y")) %>% 
    map_df(as.list) 
## # A tibble: 10 × 2 
##  x  y 
## <int> <int> 
## 1  73 348 
## 2  73 243 
## 3 145 348 
## 4 217 348 
## 5 289 348 
## 6  27 137 
## 7  82 32 
## 8 361 348 
## 9 433 348 
## 10 505 348 

這也:

library(magrittr) 

lapply(x, getNodeCenter) %>% 
    lapply(getPoints) %>% 
    lapply(set_names, c("x", "y")) %>% 
    lapply(as.list) %>% 
    do.call(rbind.data.frame, .) 

,如果你不希望使用purrr但願意使用管道或:

do.call(rbind.data.frame, lapply(x, function(y) { 
    as.list(setNames(getPoints(getNodeCenter(y)), c("x", "y"))) 
})) 

,如果你不喜歡的管道,或:

do.call(rbind.data.frame, lapply(x, function(y) { 
    tmp <- getNodeCenter(y) 
    tmp <- getPoints(tmp) 
    tmp <- setNames(tmp, c("x", "y")) 
    as.list(tmp) 
})) 

,如果你希望它是可讀的,而不是使用purrr或管道。