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")))
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.
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.
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:
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.
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 n
th 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:
`[[`
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)
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 n
th 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 n
th 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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With