R中

2017-09-29 56 views
1

合并两个列表具有不同的结构我已经vendor_listR中

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 

我看过类似的问题Combine two lists in a dataframe in R

但它给我的错误

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" 
+0

(我是对的。你有'vendor_list'空元素!) – r2evans

+0

其实空元素不会引发错误。 NULL,但是,会。你可以快速地用空字符串或任何你喜欢的东西替换那些NULL。 – Troy

回答

2

我的猜测是,你的列表中的一个具有零长度元素。

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 
+0

它为我工作,谢谢。请upvote我的问题 –

+0

另一个ALT堆栈(setNames(vendor_list,problemtype_list))' – user20650

+1

我知道那里有一个更简单的功能......谢谢,@ user20650! – r2evans

1

你说对我不起作用作品的代码 - 我叫东西pv

> 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 
> 
+0

我会添加每个列表的str输出。因为我仍然收到错误 –

+0

请参阅编辑 –

+0

当'mapply'返回一个'array'副作为'list'时,如果没有'SIMPLIFY = FALSE',你可能会失败。尽管只有在所有结果完全相同的情况下才会发生这种情况,但仍值得警惕。 – r2evans