How to append vectors inside lists with grace - r

I have a vector appended within a list. The entry successively grows.
li <- list()
for(i in 1:10)
{
v <- runif(2)
if(i==1)
{
li[[1]] <- v
} else {
li[[1]] <- append(li[[1]],v)
}
}
It's ugly that I need different code for the two cases 1) li[[1]] does not exist and 2) li[[1]] exists. Any solutions?
Background:
you cant initialize a list element as you do it with a vector:
v <- NULL
v <- append(v,c(1,2,3))
works
but
li <- list()
li[[1]] <- NULL
li[[1]] <- append(li[[1]],c(1,2,3))
throws an error, since li[[1]] can't be initialized by li[[1]] <- NULL .
Update: I learned that this will work with named lists (which also adds some grace), but there may be (dynamical) cases where naming is not a good option.

I am not sure that you need a loop here. But you can pre-allocate your list to avoid dealing with empty lists. You allocate using vector like this:
n <- 10
li <- vector('list',n)
Then you just assign each element :
for(i in 1:10) {
v <- runif(sample(n,1)) ## I choose a dynamic length here
## otherwise the example don't make sense
li[[i]] <- v
}

The proper way to initialize list elements is such:
li <- list(NULL)
for(i in 1:10)
{
v <- runif(2)
li[[1]] <- append(li[[1]],v)
}
Thanks

Related

Apply a function to objects in my global environment R

This code chunk creates a 10 objects based of length of alpha.
alpha <- seq(.1,1,by=.1)
for (i in 1:length(alpha)){
assign(paste0("list_ts_ses_tune", i),NULL)
}
How do I put each function into the new list_ts_ses_tune1 ... null objects I've created? Each function puts in a list, and works if I set list_ts_ses_tune1 <- lapply ...
for (i in 1:length(alpha))
{
list_ts_ses_tune[i] <- lapply(list_ts, function(x)
forecast::forecast(ses(x,h=24,alpha=alpha[i])))
list_ts_ses_tune[i] <- lapply(list_ts_ses_tune[i], "[", c("mean"))
}
Maybe this is a better way to do this? I need each individual output in a list of values.
Edit:
for (i in 1:length(alpha))
{
list_ts_ses_tune[[i]] <- lapply(list_ts[1:(length(list_ts)/2)],
function(x)
forecast::forecast(ses(x,h=24,alpha=alpha[i])))
list_ts_ses_tune[[i]] <- lapply(list_ts_ses_tune[[i]], "[", c("mean"))
}
We can use mget to return all the objects into a list
mget(ls(pattern = '^list_ts_ses_tune\\d+'))
Also, the NULL list can be created more easily instead of 10 objects in the global environment
list_ts_ses_tune <- vector('list', length(alpha))
Now, we can just use the OP's code
for (i in 1:length(alpha))
{
list_ts_ses_tune[[i]] <- lapply(list_ts, function(x)
forecast::forecast(ses(x,h=24,alpha=alpha[i])))
}
If we want to create a single data.frame
for(i in seq_along(alpha)) {
list_ts_ses_tune[[i]] <- data.frame(Mean = do.call(rbind, lapply(list_ts, function(x)
forecast::forecast(ses(x,h=24,alpha=alpha[i]))$mean)))
}
You could simply accomplish everything by doing:
library(forecast)
list_ts_ses_tune <- Map(function(x)
lapply(alpha, function(y)forecast(ses(x,h=24,alpha=y))['mean']), list_ts)

list of dataframes in R: assignment problem

I have the following code:
child_tracks <- list()
for(i in 1:106)
{
for(j in 1:5)
{
child_tracks[[i]][[j]] <-
all_samples[[i]][sample(nrow(all_samples[[i]]),length_breakups[[i]][[j]]),]
}
}
As above, "all_samples" is a list of dataframes, while "length_breakups" is a list of lists.
When I assign the calculation to it, it throws an error
: subscript out of bounds. Although a singular variable can hold, a list
can't. For example:
temp <-
all_samples[[i]][sample(nrow(all_samples[[i]]),length_breakups[[i]][[j]]),]
child_tracks[[i]][[j]] <-
all_samples[[i]][sample(nrow(all_samples[[i]]),length_breakups[[i]][[j]]),]
The former works, the latter doesn't. I've seen that the class
definitions are all okay and so are the ranges of the "for" loop.
Just not getting around it. Any comments?
Initialise the size of the list:
child_tracks <- array(list(), c(106,5))
for(i in 1:106)
{
for(j in 1:5)
{
child_tracks[[i]][[j]] <-
all_samples[[i]][sample(nrow(all_samples[[i]]),length_breakups[[i]][[j]]),]
}
}

R - Saving the values from a For loop in a vector or list

I'm trying to save each iteration of this for loop in a vector.
for (i in 1:177) {
a <- geomean(er1$CW[1:i])
}
Basically, I have a list of 177 values and I'd like the script to find the cumulative geometric mean of the list going one by one. Right now it will only give me the final value, it won't save each loop iteration as a separate value in a list or vector.
The reason your code does not work is that the object ais overwritten in each iteration. The following code for instance does what precisely what you desire:
a <- c()
for(i in 1:177){
a[i] <- geomean(er1$CW[1:i])
}
Alternatively, this would work as well:
for(i in 1:177){
if(i != 1){
a <- rbind(a, geomean(er1$CW[1:i]))
}
if(i == 1){
a <- geomean(er1$CW[1:i])
}
}
I started down a similar path with rbind as #nate_edwinton did, but couldn't figure it out. I did however come up with something effective. Hmmmm, geo_mean. Cool. Coerce back to a list.
MyNums <- data.frame(x=(1:177))
a <- data.frame(x=integer())
for(i in 1:177){
a[i,1] <- geomean(MyNums$x[1:i])
}
a<-as.list(a)
you can try to define the variable that can save the result first
b <- c()
for (i in 1:177) {
a <- geomean(er1$CW[1:i])
b <- c(b,a)
}

Why is my list empty after execution?

I managed to fill my doi_list but it does not work if I encapsulate the code into a function. From a tutorial I've seen I assume that this should be possible but doi_list is empty after get_doi_from_category() finishes.
library(aRxiv)
get_doi_from_category <- function(category, doi_list) {
arxiv_rec <- arxiv_search(category)
arxiv_doi_list <- arxiv_rec[13]
by(arxiv_doi_list, 1:nrow(arxiv_doi_list),
function(row) {
if(nchar(row) > 0) {
doi_list <<- c(doi_list, row)
}
})
}
doi_list <- list()
get_doi_from_category('cat:stat.ML', doi_list)
for(doi in doi_list)
{
print(doi)
}
get_doi_from_category('cat:stat.CO', doi_list)
get_doi_from_category('cat:stat.ME', doi_list)
get_doi_from_category('cat:stat.TH', doi_list)
PS: First day with R.
Here's a better way to do what you want in R:
categ <- c(CO = "cat:stat.CO", #I'm naming these elements so
ME = "cat:stat.ME", # that the corresponding elements
TH = "cat:stat.TH", # in the list are named as well.
ML = "cat:stat.ML") # Could also just set 'names(doi_list)' to 'categ'.
doi_list <-
lapply(categ, function(ctg)
(doi <- arxiv_search(ctg)$doi)[nchar(doi) > 0])
I sort of threw you in the deep end on the last line with in-line assignment of doi; a more step-by-step approach would be:
lapply(categ, function(ctg){
arxiv.df <- arxiv_search(ctg)
doi <- arxiv.df$doi
doi[nchar(doi) > 0]})

R programming: save three dimensional outputs after loop

I am new to R and I would like to save the out puts after the loop
for (i in 1:5) {
for (d in 1:10) {
fonction1
fonction2
fonction3
}
}
At the end I would like to have 1 list-> contains 5 list-> contains 1*10 data frame -> contains certain number*3 numeric data. (I dont know if im saying it correctly, what i want to have is: like in Matlab, there is a 1*5 structure -> contains five 1*10 structure -> contain certain number*3 numeric data).
thanks in advance
Looks like you are looking after something like the following:
out <- list()
for (i in 1:5) {
outList <- list()
for (d in 1:10) {
outVect <- c()
outVect[1] <- fonction1()
outVect[2] <- fonction2()
outVect[3] <- fonction3()
outList[[d]] <- outVect
}
out[[i]] <- outList
}
Then you can look at:
str(out)
to see the structure of your answer
Try this:
lst <- lapply(1:5, function(i) {
lapply(1:10, function(d) {
data.frame(function1(),
function2(),
function3())
})
})
Assuming function1, function2 and function3 all return equal-length vectors, the above code should produce your desired object. You can use i and d identically as you would have used them in your for loop code.

Resources