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 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:
`[[` 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 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
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