I am trying to transpose a table I have created from a list of lists.
Each nested list has this format:
list(storm_name=NA, storm_level=NA, file_date=NA, file_time=NA,
date=NA, time=NA, actual_or_forecast=NA, lat=NA, long=NA, max_wind=NA,
gusts=NA, eye_speed=NA, eye_location=NA, storm_end=NA)
In short, each row has 14 elements within it.
storm_df <- as.data.frame(matrix(unlist(list1), nrow=length(unlist(list1[1]))))
The code I have written above so far creates the table where the orientation is 14 rows x N (number of inner lists) columns whereas I would like it to be N rows x 14 columns.
Does anyone see what I am doing wrong?
Thanks in advance!
Let's use do.call, rbind, and lapply:
## data
l1 <- list(storm_name=NA, storm_level=NA, file_date=NA, file_time=NA,
date=NA, time=NA, actual_or_forecast=NA, lat=NA, long=NA, max_wind=NA,
gusts=NA, eye_speed=NA, eye_location=NA, storm_end=NA)
big_list <- list(l1, l1, l1)
## make data.frame
do.call('rbind', lapply(big_list, data.frame))
Stepping through this, first we run lapply on big_list, so for each item in big_list, we create a data.frame. Try data.frame(l1) to see the result of each call.
Then we use do.call('rbind', ...) because the lapply returns a lists of data.frames, we want to "stack" the data on top of each other.
Related
I have a long list of lists (> 100k) and need to iteratively loop through each list and extract the "id" - which i can do easily by constructing lapply in a for loop.
Here is an example of the lists:
l1 <- list(id="002e2b45555652749339ab9c34359fb6", key="2", value="xx")
l2 <- list(id="002e2b433226527493jsab9c34353fb6", key="4", value="zz")
l3 <- list(list1, list2)
I do the looping with:
for(i in 1:20) {
lapply(l3$id[[i]][1], function (x) print(x))
}
Basically printing all the elements of each list of the id - which is nice.
I ultimately want to construct a matrix / dataframe with all the "ids" in rows. What bugs me is, the print in my loop works well, printing out all ids from all the lists - although I cannot bind my rows to a dataframe or a matrix etc. i was trying out something like - ain't doing what i want (although not getting an error etc.)
for(i in 1:20) {
lapply(l3$id[[i]][1], function (x) rbind(x))
}
SO the desired output shall be (preferrably as a dataframe).
[1] "002e2b45555652749339ab9c3400cc52"
[1] "002e2b45555652749339ab9c34040525"
If you want a vector of the IDs you can do
sapply(l3, "[[", "id")
or using tidyverse functions
purrr::map_chr(l3, "id")
No need for loops for stuff like this in R.
using base R:
s=aggregate(.~ind,stack(setNames(l3,1:length(l3))),identity)
ind values.1 values.2 values.3
1 1 002e2b45555652749339ab9c34359fb6 2 xx
2 2 002e2b433226527493jsab9c34353fb6 4 zz
if you just need the id's
s$values[,1]
[1] "002e2b45555652749339ab9c34359fb6" "002e2b433226527493jsab9c34353fb6"
I have a list of lists, where some lists are NULL (contain nothing), and some lists contains 12 columns and 1 row. lets say this list of lists is named: pages.
I would like to merge the lists that contain the 12 columns and 1 row into a dataframe. so that I have a final dataframe of 12 columns and x rows.
I first tried:
final_df <- Reduce(function(x,y) merge(x, y, all=TRUE), pages)
which yielded a dataframe with the right 12 columns, but no rows, so it was empty.
I then tried:
listofvectors <- list()
for (i in 1:length(pages)) {listofvectors <- c(listofvectors, pages[[i]])}
which just pasted every list below each other.
I finally tried playing with:
final<-do.call(c, unlist(pages, recursive=FALSE))
which only resulted in a very long value.
What am I missing? Who can help me out? Thanks a lot for your input.
The merge function is for joining data on common column values (commonly called a join). You need to use rbind instead (the r for row, use cbind to stick columns together).
do.call(rbind, pages) # equivalent to rbind(pages[[1]], pages[[2]], ...)
do.call(rbind, pages[lengths(pages) > 0]) # removing the 0-length elements
If you have additional issues, please provide a reproducible example in your question. This code works on this example:
x = list(data.frame(x = 1), NULL, data.frame(x = 2))
do.call(rbind, x)
# x
# 1 1
# 2 2
I have written a function that takes three arguments:
create.template <- function(t.list, x, y){
temp <- cbind(get(t.list[x]), get(t.list[y]), NA)
}
The output of this function is a data.frame with 11 columns and 17 rows.
Now I would like to create a loop over the function with two lists, one for x and one for y. Thereby
x.list <- list(1,2,3)
y.list <- list(4,5,6)
In the final step I would like to establish something like
for (x in x.list and y in y.list){
create.template(t.list, x, y)
}
and possibly combine the resulting dataframes (3 dataframes with 11 columns each) rowwise in one final dataframe.
I know that you can do this in Python with the zip() function and then append the results easily by append() and concatenate(), but I have not found an equivalent in R so far. Any help is highly appreciated!
We can get the values of multiple objects with mget, use either Reduce or do.call to cbind the list of vectors
Reduce(cbind, c(mget(ls(pattern = "\\.list")), NA))
Or
do.call(cbind, c(mget(c("x.list", "y.list")), NA))
I have a large list of 2 elements containing lists of species containing lists of 25 vectors, resembling a set like this:
l1 <- list(time=runif(100), space=runif(100))
l2 <- list(time=runif(100), space=runif(100))
list1 <- list(test1=list(species1=l1, species2=l2),test2=list(species1=l1, species2=l2))
I think, its essentially a list of a list of lists.of vectors.
I want to create a data.frame from all space-vectors of all 'species' in just one of the two sublists:
final <- as.data.frame(cbind(unlist(list1[[2]]$species1$space), unlist(list1[[2]]$species2$space)))
names(final) <- names(list1[[2]])
Essentially, i need a loop/apply command that navigates me through list1[[2]]$species and picks all vectors called space.
Thank you very much!
We can use a nested loop to extract the 'space' elements
data.frame(lapply(list1, function(x)
sapply(x, "[", 'space')))
Consider the following list of lists:
lst = list(list(c(1,2), c(3,4)),list(c(5,6), c(7,8)),list(c(9,10), c(11,12)))
The list lst contains three lists, each list containing two vectors as elements. I would like to combine the elements of the underlying lists by index. In other words, I would like to merge vector 1 from list 1 with that of list 2 and list 3, and vector 2 from list 1 with that of list 2 and list 3, etc...
This is the result I am looking to achieve:
res = list(c(1,2,5,6,9,10), c(3,4,7,8,11,12))
I know that this can be achieved as follows in case of two separate lists:
mapply(c, lst1, lst2)
However, I am not sure how to replicate the same logic using a list of lists.
Any efficient way to achieve that? Please keep in mind that in reality, lst is a list of 5000 lists, and each underlying list contains a large number of vectors.
Thanks!
You can do:
do.call(Map, c(c, lst))
You're on the right track:
do.call(function(...) mapply(c,...,SIMPLIFY = FALSE),args = lst)
[[1]]
[1] 1 2 5 6 9 10
[[2]]
[1] 3 4 7 8 11 12
I was looking for something along the lines of the OP's question... but with a list of data frames instead of vectors. In that case, slightly modifying #joran's answer above gives the desired result. Consider:
mylist <-
lapply(1:2, function(y){
df1 <- data.frame(a=y, b=y^2, c=y^3)
df2 <- data.frame(d=y, e=y+1)
return(list(df1=df1, df2=df2))
})
You can then re-combine the sub-list elements into separate data frames based on their common indexes:
mylist2 <- do.call(function(...) Map("rbind", ...), mylist)