Combine non NA values for n Lists R

落爺英雄遲暮 提交于 2019-12-24 20:17:45

问题


A - I have a list containing igraph graph objects:

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]:

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 e.g. a color, which lines up with the order of the original objects (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? (E.g. I have n entries)?

To get:

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

What I tried (which does not work for n color_ variables:

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. How can I adjust this to account for n elements?

I considered using multiple nested IFELSE statements such as here and here a 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)......))

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.

Many thanks for your help.


回答1:


You can use Reduce to "cumulatively" apply a function over a vector:

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

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_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"


来源:https://stackoverflow.com/questions/47637321/combine-non-na-values-for-n-lists-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!