简体   繁体   English

合并n个列表R的非NA值

[英]Combine non NA values for n Lists R

A - I have a list containing igraph graph objects: 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

I can combine these into a single object using [union][1] : 我可以使用[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):

From this, I can extract particular attributes eg a color , which lines up with the order of the original objects (1 - 2): 从中,我可以提取特定属性,例如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"

How can I extract the non NA values in $color_1 and $color_2 and merge them into a new list when I have an arbitrary number of color_n entries? 当我有任意数量的color_n条目时,如何提取$color_1$color_2的非NA值并将它们合并到新列表中? (Eg I have n entries)? (例如,我有n个条目)?

To get: 要得到:

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

What I tried (which does not work for n color_ variables: 我尝试了什么(不适用于n color_变量:

In this simple case I can do what this answer did here: 在这种简单的情况下,我可以执行以下答案:

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" 

However, in reality my list could have n elements. 但是,实际上我的列表可以包含n元素。 How can I adjust this to account for n elements? 我该如何调整以解决n元素?

I considered using multiple nested IFELSE statements such as here and here a la: 我认为使用多个嵌套IFELSE语句,如这里这里一拉:

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)......))

This does not work for unknown n attributes and does not solve the issue of having an unknown number n of attributes to work with. 这不适用于未知的n属性,也无法解决要使用的未知数量的n个属性的问题。

Many thanks for your help. 非常感谢您的帮助。

You can use Reduce to "cumulatively" apply a function over a vector: 您可以使用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"

In this case, Reduce applied the function to the first and second elements, then to that result and the third element, then to that result and the fourth element. 在这种情况下, Reduce将函数应用于第一个和第二个元素,然后应用于该结果和第三个元素,然后应用于该结果和第四个元素。 If the list were longer, it would've kept going on that way. 如果列表较长,它将一直保持这种状态。

Edit for your specific situation: save the list of attributes, find which have names like color_n , and then use the Reduce solution on those. 针对您的特定情况进行编辑:保存属性列表,找到名称类似于color_n的属性,然后对它们使用Reduce解决方案。

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

Because I don't have your data, let's just say combine_attributes looks like the color_samples created above with an extra element: 因为我没有您的数据,所以我们只能说combine_attributes看起来像color_samples创建的带有附加元素的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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM