在 R 中组合两个具有不同结构的列表
Combine two lists with different structure in R
我有vendor_list
vendor_list[57:59]
[[1]]
[1] "ibm"
[[2]]
[1] "apache" "canonical" "apple" "novell"
[[3]]
[1] "gnu" "oracle"
我有problemtype_list
problemtype_list[57:59]
[[1]]
[1] "NVD-CWE-Other"
[[2]]
[1] "NVD-CWE-Other"
[[3]]
[1] "CWE-824"
我需要将它们组合起来制作一个数据框,使得
A B
ibm NVD-CWE-Other
apache NVD-CWE-Other
canonical NVD-CWE-Other
apple NVD-CWE-Other
novelle NVD-CWE-Other
gnu CWE-824
oracle CWE-824
我看过类似的问题
但它给我错误
do.call(rbind, Map(data.frame, A=problemtype_list, B=vendor_list))
Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :
arguments imply differing number of rows: 1, 0
编辑
我的每个列表结构
str(vendor_list)
$ : chr "cisco"
$ : NULL
$ : chr [1:5] "redhat" "novell" "debian" "oracle" ...
$ : chr [1:4] "redhat" "novell" "debian" "google"
$ : chr [1:4] "redhat" "novell" "debian" "google"
str(problemtype_list)
$ : chr "CWE-254"
$ : chr "CWE-79"
$ : chr "NVD-CWE-Other"
$ : chr "NVD-CWE-Other"
$ : chr "CWE-254"
$ : chr "CWE-189"
$ : chr "CWE-119"
你说的代码对我不起作用 - 我已经调用了 p
和 v
:
> v = list("ibm",c("apache","canonical","apple","novelle"),c("gnu","oracle"))
> p = list("NVD-CWE-Other","NVD-CWE-Other","CWE-824")
> p
[[1]]
[1] "NVD-CWE-Other"
[[2]]
[1] "NVD-CWE-Other"
[[3]]
[1] "CWE-824"
> v
[[1]]
[1] "ibm"
[[2]]
[1] "apache" "canonical" "apple" "novelle"
[[3]]
[1] "gnu" "oracle"
然后你的代码:
> do.call(rbind, Map(data.frame, A=p, B=v))
A B
1 NVD-CWE-Other ibm
2 NVD-CWE-Other apache
3 NVD-CWE-Other canonical
4 NVD-CWE-Other apple
5 NVD-CWE-Other novelle
6 CWE-824 gnu
7 CWE-824 oracle
所以您的数据结构可能不同。
或者:
> do.call(rbind.data.frame,mapply(cbind,v,p))
V1 V2
1 ibm NVD-CWE-Other
2 apache NVD-CWE-Other
3 canonical NVD-CWE-Other
4 apple NVD-CWE-Other
5 novelle NVD-CWE-Other
6 gnu CWE-824
7 oracle CWE-824
>
我猜你的列表中有一个零长度元素。
vendor_list <- list("ibm", c("apache", "canonical", "apple", "novell"), c("gnu", "oracle"))
problemtype_list <- list("NVD-CWE-Other", "NVD-CWE-Other", "CWE-824")
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
# 6 gnu CWE-824
# 7 oracle CWE-824
但是,如果我们提供一个空位:
vendor_list[[3]] <- character(0)
vendor_list
# [[1]]
# [1] "ibm"
# [[2]]
# [1] "apache" "canonical" "apple" "novell"
# [[3]]
# character(0)
...和快速测试:
any(lengths(vendor_list) == 0)
# [1] TRUE
any(lengths(problemtype_list) == 0)
# [1] FALSE
...然后合并失败:
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, (from pit-roads.R!8460QVH#21) :
# arguments imply differing number of rows: 0, 1
您可以将有问题的条目替换为有意义的内容(例如 NA
),也可以删除它们。使用哪种方法完全取决于您的用途。
替换:
vendor_list[lengths(vendor_list) == 0] <- NA
problemtype_list[lengths(problemtype_list) == 0] <- NA
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
# 6 <NA> CWE-824
删除:
keepthese <- (lengths(vendor_list) > 0) & (lengths(problemtype_list) > 0)
keepthese
# [1] TRUE TRUE FALSE
vendor_list <- vendor_list[keepthese]
problemtype_list <- problemtype_list[keepthese]
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
你可以用mapply
解决问题
df=mapply(c,vendor_list,problemtype_list)
这给你一个 data.frame 包含列表中的值
我有vendor_list
vendor_list[57:59]
[[1]]
[1] "ibm"
[[2]]
[1] "apache" "canonical" "apple" "novell"
[[3]]
[1] "gnu" "oracle"
我有problemtype_list
problemtype_list[57:59]
[[1]]
[1] "NVD-CWE-Other"
[[2]]
[1] "NVD-CWE-Other"
[[3]]
[1] "CWE-824"
我需要将它们组合起来制作一个数据框,使得
A B
ibm NVD-CWE-Other
apache NVD-CWE-Other
canonical NVD-CWE-Other
apple NVD-CWE-Other
novelle NVD-CWE-Other
gnu CWE-824
oracle CWE-824
我看过类似的问题
但它给我错误
do.call(rbind, Map(data.frame, A=problemtype_list, B=vendor_list))
Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :
arguments imply differing number of rows: 1, 0
编辑
我的每个列表结构
str(vendor_list)
$ : chr "cisco"
$ : NULL
$ : chr [1:5] "redhat" "novell" "debian" "oracle" ...
$ : chr [1:4] "redhat" "novell" "debian" "google"
$ : chr [1:4] "redhat" "novell" "debian" "google"
str(problemtype_list)
$ : chr "CWE-254"
$ : chr "CWE-79"
$ : chr "NVD-CWE-Other"
$ : chr "NVD-CWE-Other"
$ : chr "CWE-254"
$ : chr "CWE-189"
$ : chr "CWE-119"
你说的代码对我不起作用 - 我已经调用了 p
和 v
:
> v = list("ibm",c("apache","canonical","apple","novelle"),c("gnu","oracle"))
> p = list("NVD-CWE-Other","NVD-CWE-Other","CWE-824")
> p
[[1]]
[1] "NVD-CWE-Other"
[[2]]
[1] "NVD-CWE-Other"
[[3]]
[1] "CWE-824"
> v
[[1]]
[1] "ibm"
[[2]]
[1] "apache" "canonical" "apple" "novelle"
[[3]]
[1] "gnu" "oracle"
然后你的代码:
> do.call(rbind, Map(data.frame, A=p, B=v))
A B
1 NVD-CWE-Other ibm
2 NVD-CWE-Other apache
3 NVD-CWE-Other canonical
4 NVD-CWE-Other apple
5 NVD-CWE-Other novelle
6 CWE-824 gnu
7 CWE-824 oracle
所以您的数据结构可能不同。
或者:
> do.call(rbind.data.frame,mapply(cbind,v,p))
V1 V2
1 ibm NVD-CWE-Other
2 apache NVD-CWE-Other
3 canonical NVD-CWE-Other
4 apple NVD-CWE-Other
5 novelle NVD-CWE-Other
6 gnu CWE-824
7 oracle CWE-824
>
我猜你的列表中有一个零长度元素。
vendor_list <- list("ibm", c("apache", "canonical", "apple", "novell"), c("gnu", "oracle"))
problemtype_list <- list("NVD-CWE-Other", "NVD-CWE-Other", "CWE-824")
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
# 6 gnu CWE-824
# 7 oracle CWE-824
但是,如果我们提供一个空位:
vendor_list[[3]] <- character(0)
vendor_list
# [[1]]
# [1] "ibm"
# [[2]]
# [1] "apache" "canonical" "apple" "novell"
# [[3]]
# character(0)
...和快速测试:
any(lengths(vendor_list) == 0)
# [1] TRUE
any(lengths(problemtype_list) == 0)
# [1] FALSE
...然后合并失败:
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, (from pit-roads.R!8460QVH#21) :
# arguments imply differing number of rows: 0, 1
您可以将有问题的条目替换为有意义的内容(例如 NA
),也可以删除它们。使用哪种方法完全取决于您的用途。
替换:
vendor_list[lengths(vendor_list) == 0] <- NA
problemtype_list[lengths(problemtype_list) == 0] <- NA
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
# 6 <NA> CWE-824
删除:
keepthese <- (lengths(vendor_list) > 0) & (lengths(problemtype_list) > 0)
keepthese
# [1] TRUE TRUE FALSE
vendor_list <- vendor_list[keepthese]
problemtype_list <- problemtype_list[keepthese]
do.call(rbind.data.frame, Map(data.frame, A=vendor_list, B=problemtype_list))
# A B
# 1 ibm NVD-CWE-Other
# 2 apache NVD-CWE-Other
# 3 canonical NVD-CWE-Other
# 4 apple NVD-CWE-Other
# 5 novell NVD-CWE-Other
你可以用mapply
解决问题
df=mapply(c,vendor_list,problemtype_list)
这给你一个 data.frame 包含列表中的值