S4 class 列表到数据框
S4 class list to data frame
我是 S4 classes 的新手,四处寻找解决方案但失败了:(
我有一个 S4 class 列表,不确定它是否是嵌套列表,但我想将它更改为数据框。我的列表看起来像这个名为 z
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
有人可以帮我吗?
如果你想要 "one-liner":
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
或管道。
我是 S4 classes 的新手,四处寻找解决方案但失败了:( 我有一个 S4 class 列表,不确定它是否是嵌套列表,但我想将它更改为数据框。我的列表看起来像这个名为 z
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
有人可以帮我吗?
如果你想要 "one-liner":
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
或管道。