Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take the union of element in a nested list in R

Tags:

r

I have a nested list in say lst(all the elements are of class int). I don't know the length of lst in advance; however I do know that each element of lst is a list of length say k

length(lst[[i]]) # this equals k and is known in advance, 
                 # this is true for i = 1 ... length(lst)

How do I take the union of the 1st element, 2nd element, ..., kth element of all the elements of lst

Specifically, if the length of lst is n, I want (not R code):

# I know that union can only be taken for 2 elements, 
# following is for illustration purposes
listUnion1 <- union(lst[[1, 1]], lst[[2, 1]], ..., lst[[n, 1]])
listUnion2 <- union(lst[[1, 2]], lst[[2, 2]], ..., lst[[n, 2]])
.
.
.
listUnionk <- union(lst[[1, k]], lst[[2, k]], ..., lst[[n, k]])

Any help or pointers are greatly appreciated.

Here is a dataset that can be used, n = 3 and k = 2

list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")), 
    structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")), 
    structure(list(a = 12, b = 12), .Names = c("a", "b")))
like image 966
suncoolsu Avatar asked Apr 25 '11 05:04

suncoolsu


People also ask

How to select the second element of a nested list in R?

Below are the steps used in the R program to select the second element of a given nested list. In this R program, we directly give the values to a built-in function lapply (). Here we are using the variable values_lst for holding the nested list. And variable rslt_lst is the result list after applying the function to each element of values_lst.

How to use the R Union function for two lists?

It is also possible to use the R union function for two lists. Let’s first create two lists in R: Note: The first element of both lists is equal (i.e. list_1 [ [1]] == list_2 [ [1]]). Graphic 2: RStudio Console Output after Applying union () to Two Lists. Graphic 2 shows the output of the RStudio console after the application of union to two lists.

How to append list objects to a nested list in R?

The following R programming syntax illustrates how to append list objects to a nested list within a for-loop. To set up the example, we first have to create a vector containing all list names of lists that we want to combine: Next, we have to create an empty list to which we will insert our list objects:

How to create two lists in R?

Let’s first create two lists in R: Note: The first element of both lists is equal (i.e. list_1 [ [1]] == list_2 [ [1]]). Graphic 2: RStudio Console Output after Applying union () to Two Lists.


2 Answers

Here is a general solution, similar in spirit to that of @Ramnath, but avoiding the use of union() which is a binary function. The trick is to note that union() is implemented as:

unique(c(as.vector(x), as.vector(y)))

and the bit inside unique() can be achieved by unlisting the nth component of each list.

The full solution then is:

unionFun <- function(n, obj) {
    unique(unlist(lapply(obj, `[[`, n)))
}
lapply(seq_along(lst[[1]]), FUN = unionFun, obj = lst)

which gives:

[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

[[2]]
 [1]  6  7  8  9 10 11  1  2  3  4  5 12

on the data you showed.

A couple of useful features of this are:

  • we use `[[` to subset obj in unionFun. This is similar to function(x) x$a in @Ramnath's Answer. However, we don't need an anonymous function (we use `[[` instead). The equivalent to @Ramnath's Answer is: lapply(lst, `[[`, 1)
  • to generalise the above, we replace the 1 above with n in unionFun(), and allow our list to be passed in as argument obj.

Now that we have a function that will provide the union of the nth elements of a given list, we can lapply() over the indices k, applying our unionFun() to each sub-element of lst, using the fact that the length of lst[[1]] is the same as length(lst[[k]]) for all k.

If it helps to have the names of the nth elements in the returned object, we can do:

> unions <- lapply(seq_along(lst[[1]]), FUN = unionFun, obj = lst)
> names(unions) <- names(lst[[1]])
> unions
$a
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

$b
 [1]  6  7  8  9 10 11  1  2  3  4  5 12
like image 105
Gavin Simpson Avatar answered Oct 14 '22 14:10

Gavin Simpson


Here is one solution

# generate dummy data
x1 = sample(letters[1:5], 20, replace = T)
x2 = sample(letters[1:5], 20, replace = T)
df = data.frame(x1, x2, stringsAsFactors = F)

# find unique elements in each column
union_df = apply(df, 2, unique)

Let me know if this works

EDIT: Here is a solution for lists using the data you provided

mylist = list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")), 
              structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")), 
              structure(list(a = 12, b = 12), .Names = c("a", "b")))
list_a = lapply(mylist, function(x) x$a)
list_b = lapply(mylist, function(x) x$b)

union_a = Reduce(union, list_a)
union_b = Reduce(union, list_b)

If you have more than 2 elements in your list, we could generalize this code.

like image 33
Ramnath Avatar answered Oct 14 '22 14:10

Ramnath