合并n个列表R的非NA值

时间:2017-12-04 16:03:07

标签: r list if-statement nested igraph

A - 我有一个包含igraph图形对象的列表:

goodgg

[[1]]
IGRAPH UN-- 3 3 -- 
+ attr: name (v/c), color (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 89315--89316 89315--89928 89316--89928

[[2]]
IGRAPH UN-- 3 2 -- 
+ attr: name (v/c), color (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 106277--106278 106278--106279

我可以使用[union][1]

将这些组合成一个对象
combine = graph.union(goodgg[[1]], goodgg[[2]], byname=T)

combine
IGRAPH UN-- 6 5 -- 
+ attr: color_1 (v/c), color_2 (v/c), name (v/c)
+ edges (vertex names):

由此,我可以提取特定属性,例如a color,与原始对象的顺序排列(1 - 2):

as.list(get.vertex.attribute(combine))
$color_1
[1] "red"    "red"    "orange" NA       NA       NA      

$color_2
[1] NA    NA    NA    "red" "red" "red"

$name
[1] "89315"  "89316"  "89928"  "106277" "106278" "106279"

如何在NA$color_1中提取非$color_2值,并在拥有任意数量的color_n条目时将它们合并到一个新列表中? (例如,我有n个条目)?

获得:

[1] "red"    "red"    "orange" "red"    "red"    "red"

我尝试了什么(这对n color_变量不起作用:

在这个简单的例子中,我可以做this回答在这里做的事情:

V(combine)$color <- ifelse(is.na(get.vertex.attribute(combine)$color_1), get.vertex.attribute(combine)$color_2,get.vertex.attribute(combine)$color_1)

get.vertex.attribute(combine)$color
[1] "red"    "red"    "orange" "red"    "red"    "red" 

然而,实际上我的列表可能有n个元素。如何根据n元素进行调整?

我考虑过使用多个嵌套的IFELSE语句,例如herehere la:

V(combine)$color <- ifelse(is.na(get.vertex.attribute(combine)$color_1), ifelse(is.na(get.vertex.attribute(combine)$color_2), ifelse(get.vertex.attribute(combine)$color_3)......))

这不适用于未知的n属性,并且无法解决使用未知数量n属性的问题。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

您可以使用Reduce“累积”在向量上应用函数:

set.seed(125)

color_choices <- c("red", "orange", NA)

color_samples <- replicate(
  4,
  sample(color_choices, 5, replace = TRUE),
  simplify = FALSE
)
color_samples
# [[1]]
# [1] NA       "red"    "red"    "orange" NA
# 
# [[2]]
# [1] NA       "orange" "red"    "orange" "orange"
# 
# [[3]]
# [1] "red"    NA       "orange" "red"    "orange"
# 
# [[4]]
# [1] "orange" "orange" NA       NA       NA

Reduce(
  f = function(a, b) ifelse(is.na(a), b, a),
  x = color_samples
)
# [1] [1] "red"    "red"    "red"    "orange" "orange"

在这种情况下,Reduce将函数应用于第一个和第二个元素,然后应用于该结果和第三个元素,然后应用于该结果和第四个元素。如果列表更长,它就会继续这样。

针对您的具体情况进行编辑:保存属性列表,找到名称为color_n的属性列表,然后对其使用Reduce解决方案。

combine_attributes <- as.list(get.vertex.attribute(combine))

由于我没有您的数据,我们只需说combine_attributes看起来就像上面创建的color_samples一样有一个额外的元素:

combine_attributes
# $color_1
# [1] NA       "red"    "red"    "orange" NA      
# 
# $color_2
# [1] NA       "orange" "red"    "orange" "orange"
# 
# $color_3
# [1] "red"    NA       "orange" "red"    "orange"
# 
# $color_4
# [1] "orange" "orange" NA       NA       NA      
# 
# $name
# [1] "89315"  "89316"  "89928"  "106277" "106278"

color_attributes <- grep(
  "^color_\\d+$",
  names(combine_attributes),
  value = TRUE
)

color_attributes
# [1] "color_1" "color_2" "color_3" "color_4"

Reduce(
  f = function(a, b) ifelse(is.na(a), b, a),
  x = combine_attributes[color_attributes]
)
# [1] "red"    "red"    "red"    "orange" "orange"
相关问题