concatenate vectors from two lists by names [duplicate] - r

This question already has answers here:
Merge Two Lists in R
(9 answers)
Merge contents within list of list by duplicate name
(1 answer)
Closed 3 years ago.
So I'm heavily simplifying my actual problem, but I am trying to find a way to append values inside vectors from one list, to values in vectors in another list, and do it by name ( assuming the two lists are not ordered).So this is the setup to the problem ( the numbers themselves are arbitrary here):
Data1 <- list( c(1),c(2),c(3))
names(Data1) <- c("A", "B","C")
Data2 <- list(c(11), c(12), c(13))
names(Data2) <- c("B","A","C")
Now what Im trying to do, is find a way to get a third list - say Data3, so that calling Data3[["A"]] will give me the same result as calling c(1,12):
[1] 1 12
so >Data3 should give:
[1] 1 12
[2] 2 11
[3] 3 13
Essentially im looking to append many values from one list of vectors, to another list of vectors, and do it by names rather than order, if that makes sense. (I did think about trying some loops, but I feel like there should be another way that is simpler)

nm = names(Data1)
setNames(lapply(nm, function(x){
c(Data1[[x]], Data2[[x]])
}), nm)
#$A
#[1] 1 12
#$B
#[1] 2 11
#$C
#[1] 3 13

list(do.call("cbind", list(Data1, Data2)))
[,1] [,2]
A 1 11
B 2 12
C 3 13
If you don't mind your output to be a dataframe:
Data3 <- rbind(data.frame(Data1), data.frame(Data2))
Then Data3[["A"]] will give you:
[1] 1 12

We can use Map and arrange the elements of Data2 in the same order as Data1 (or vice versa) using names and then concatenate them.
Map(c, Data1, Data2[names(Data1)])
#$A
#[1] 1 12
#$B
#[1] 2 11
#$C
#[1] 3 13

Related

R column names as list instead of vector [duplicate]

The vector is like this:
c(1,2,3)
#[1] 1 2 3
I need something like this:
list(1,2,3)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#[[3]]
#[1] 3
I tried this:
list(c(1,2,3))
#[[1]]
#[1] 1 2 3
Simple, just do this:
as.list(c(1,2,3))
An addition to the accepted answer: if you want to add a vector to other elements in a longer list, as.list() may not produce what you expect. For example: you want to add 2 text elements and a vector of five numeric elements (1:5), to make a list that is 7 elements long.
L<-list("a","b",as.list(1:5))
Oops: it returns a list with 3 elements, and the third element has a sub-list of 5 elements; not what we wanted! The solution is to join two separate lists:
L1<-list("a","b")
L2<-as.list(1:5)
L<-c(L1,L2) #7 elements, as expected

Create a list with True or False [duplicate]

The vector is like this:
c(1,2,3)
#[1] 1 2 3
I need something like this:
list(1,2,3)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#[[3]]
#[1] 3
I tried this:
list(c(1,2,3))
#[[1]]
#[1] 1 2 3
Simple, just do this:
as.list(c(1,2,3))
An addition to the accepted answer: if you want to add a vector to other elements in a longer list, as.list() may not produce what you expect. For example: you want to add 2 text elements and a vector of five numeric elements (1:5), to make a list that is 7 elements long.
L<-list("a","b",as.list(1:5))
Oops: it returns a list with 3 elements, and the third element has a sub-list of 5 elements; not what we wanted! The solution is to join two separate lists:
L1<-list("a","b")
L2<-as.list(1:5)
L<-c(L1,L2) #7 elements, as expected

Count within multiple nested lists R

Suppose I have a list of length 2, within which is another list of length 2, within which there is a data frame of numbers coded as either 0, 1 or 2 (bear with me!):
set.seed(42)
l1<-data.frame(sample(0:2, 5, replace = TRUE))
l2<-data.frame(sample(0:2, 5, replace = TRUE))
l<-list(l1,l2)
ll<-list(list(l,l), list(l,l))
I need to count the number of times either 1 or 2 appears within each data frame. I then need to sum these counts across all counts at the level above.
So for ll[[1]][[1]][[1]] the count would be 1, for ll[[1]][[1]][[2]] the count would be 4. Across those two dataframes the sum would be 5.
To give a more plain-English description of the real data I'm working with: the top level is the number of species (in this example, 2 species), the level below that is the year when data was recorded (in this example, data is collected in 2 different years). Below that is a location within which data are recorded. I need to know that, within years, how many times 1 or 2 appears across all locations (within that year).
There is perhaps a better way to describe this but so far it's eluding me. Any help would be appreciated.
We can use purrr functions.
library(purrr)
map(ll, function(x) transpose(x) %>% map(~sum(unlist(.x) != 0)))
#[[1]]
#[[1]][[1]]
#[1] 2
#[[1]][[2]]
#[1] 8
#[[2]]
#[[2]][[1]]
#[1] 2
#[[2]][[2]]
#[1] 8
A bit nested, but the solution should work:
lapply(ll,
function(l)
lapply(l,
function(li) sum(unlist(li) %in% 1:2)))
# [[1]]
# [[1]][[1]]
# [1] 5
#
# [[1]][[2]]
# [1] 5
#
#
# [[2]]
# [[2]][[1]]
# [1] 5
#
# [[2]][[2]]
# [1] 5

how to acces list elements based on condition in r [duplicate]

This question already has answers here:
Remove empty elements from list with character(0)
(5 answers)
Closed 3 years ago.
This sseems me very simple, however I can not get good graps on it. Lets say I have list like this:
my_list=list(integer(0),c(4,3,3),integer(0),integer(0),c(5,2,5),integer(0))
I used integer(0) to make it similar to my original data but any condition here is applicable. Now i want to extract from my list only those elements that are NOT integer(0) making new 2-element list like this:
list_I_try_to_make=list(c(4,3,3),c(5,2,5))
I know how to do this for data frame but I am not sure how to correctly adress each element of list. I tried lapply with condition for each element but this simply returns me new list with same length where each element is an answer (if length>0 it only returns TRUE/FALSE)
You can use the purrr package which is very convenient when working with lists.
library(purrr)
keep(my_list, function(x) length(x) > 0)
You can use lengths
my_list[lengths(my_list) > 0]
[[1]]
[1] 4 3 3
[[2]]
[1] 5 2 5
This is one solution :
my_list[ !unlist(lapply(my_list,identical,integer(0))) ]
Try with this:
my_filter=unlist(lapply(my_list,length))>0
my_list[my_filter]
[[1]]
[1] 4 3 3
[[2]]
[1] 5 2 5
You can use Filter:
my_list <- list(integer(0),c(4,3,3),integer(0),integer(0),c(5,2,5),integer(0))
Filter(function(x) length(x)>0, my_list)
# [[1]]
# [1] 4 3 3
#
# [[2]]
# [1] 5 2 5

How to order list by median?

I'm quite new to R and having some problems understanding the reorder function.
Lets say i have a list with 3 vectors like:
myList <- (c(7,5,2),c(2,3,4),c(1,1,1))
and I want my list to be reordered by the median of each vector so that boxplotting the list gives me an ordered plot. Now how would I do this? I read the Help description for ?reorder but I cant seem to adapt the given example for my list.
any help would be appreciated
I think you want
myList <- list(c(7,5,2),c(2,3,4),c(1,1,1))
unordered.median <- unlist(lapply(myList, median))
ordered.median <- order(unordered.median)
myList[ordered.median]
[[1]]
[1] 1 1 1
[[2]]
[1] 2 3 4
[[3]]
[1] 7 5 2

Resources