Adding Elements to a List in for Loop in R

Adding elements to a list in for loop in R

It seems like you're looking for a construct like the following:

N <- 3
x <- list()
for(i in 1:N) {
Ps <- i ## where i is whatever your Ps is
x[[paste0("element", i)]] <- Ps
}
x
# $element1
# [1] 1
#
# $element2
# [1] 2
#
# $element3
# [1] 3

Although, if you know N beforehand, then it is better practice and more efficient to allocate x and then fill it rather than adding to the existing list.

N <- 3
x <- vector("list", N)
for(i in 1:N) {
Ps <- i ## where i is whatever your Ps is
x[[i]] <- Ps
}
setNames(x, paste0("element", 1:N))
# $element1
# [1] 1
#
# $element2
# [1] 2
#
# $element3
# [1] 3

Adding Elements to List using For Loop in R

You likely need which(A2P == 1L, arr.ind = TRUE)

mat <- matrix(c(1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L), ncol = 3)

mat
# [,1] [,2] [,3]
#[1,] 1 0 1
#[2,] 0 1 0
#[3,] 0 1 1

which(mat == 1L, arr.ind = TRUE)
# row col
#[1,] 1 1
#[2,] 2 2
#[3,] 3 2
#[4,] 1 3
#[5,] 3 3

In this case, row would correspond to au_ID and col would correspond to P_ID. Then to get it in your format completely:

authorship <- which(mat == 1L, arr.ind = TRUE)
colnames(authorship) <- c('au_ID', 'P_ID')

as.data.frame(authorship)
## au_ID P_ID
##1 1 1
##2 2 2
##3 3 2
##4 1 3
##5 3 3

How to add elements to a list in R (loop)

You should not add to your list using c inside the loop, because that can result in very very slow code. Basically when you do c(l, new_element), the whole contents of the list are copied. Instead of that, you need to access the elements of the list by index. If you know how long your list is going to be, it's best to initialise it to this size using l <- vector("list", N). If you don't you can initialise it to have length equal to some large number (e.g if you have an upper bound on the number of iterations) and then just pick the non-NULL elements after the loop has finished. Anyway, the basic point is that you should have an index to keep track of the list element and add using that eg

i <- 1
while(...) {
l[[i]] <- new_element
i <- i + 1
}

For more info have a look at Patrick Burns' The R Inferno (Chapter 2).

R Add elements to a list within list

You could simply do:

unstack(stack(lapply(diamonds, class)), ind ~ values)

$factor
[1] "cut" "color" "clarity"

$integer
[1] "price"

$numeric
[1] "carat" "depth" "table" "x" "y" "z"

$ordered
[1] "cut" "color" "clarity"

Adding elements to a nested list in for loop in R

eval(), well, evaluates the expression, so it doesn't really make sens on the LHS of an assignment.

You could make it work with:

for (i in 1:length(list_of_nested_node_names )) {
position_in_list <- paste(position_in_list, "[[\"", list_of_nested_node_names[i], "\"]]", sep = "")
eval(parse(text = paste(position_in_list, "<- list(1)")))
}

(Evaluating the whole assignment).

(Also, I don't see the need of the double-arrow assignment here).

Iteratively add to sequence in for loop R

Use a while loop rather than a for loop, together with break to eventually terminate:

mylist = as.list(c(1,2,3))
i <- 1
while(TRUE){
x <- mylist[[i]]
if(x<10){
new_element <- as.list(x^2)
print(new_element)
mylist = union(mylist, new_element)
i <- i+1
} else {
break
}
}

This causes mylist to have 7 items (lists containing 1,2,3,4,9,16,81 respectively) when the loop terminates.

R: add elements to list in a loop in a tryCatch

Here is a little example of how you could solve your issue: (everyone seems to cry about <<-. Somehow assigning to global scope or global vars seems to be bad practice.)

env = environment()
env$ans <- rep("works",10)

vec <- rep(1:0,each = 5)

for (i in seq_along(vec)) {
tryCatch({ if(vec[i]) stop("error message") else {"success"} },
error = function(e) {print(i); env$ans[i] <- "error"})
}

#> env$ans
# [1] "error" "error" "error" "error" "error" "works" "works" "works" "works" "works"

So somehow if you call the property of the environment env you can access it from inside tryCatch.

Assigning value to list elements in for loop, list names depending on loop

Instead of creating 25 single lists I would suggest to put your lists into one list like so:

Note: I have set k = 2 for simplicity.

library(raster)
#> Loading required package: sp

rasterList <- list()

for (i in 1:5) {
for (j in 1:5) {
name <- paste0(i * 10, "N_0", j * 10, "E")
rasterList[[name]] <- list()
for (k in 1:2) {
raster_test <- raster(ncol = 36, nrow = 18, xmn = -1000, xmx = 1000, ymn = -100, ymx = 900)
rasterList[[name]][k] <- raster_test
}
}
}

length(rasterList)
#> [1] 25

rasterList[["10N_010E"]]
#> [[1]]
#> class : RasterLayer
#> dimensions : 18, 36, 648 (nrow, ncol, ncell)
#> resolution : 55.55556, 55.55556 (x, y)
#> extent : -1000, 1000, -100, 900 (xmin, xmax, ymin, ymax)
#> crs : NA
#>
#>
#> [[2]]
#> class : RasterLayer
#> dimensions : 18, 36, 648 (nrow, ncol, ncell)
#> resolution : 55.55556, 55.55556 (x, y)
#> extent : -1000, 1000, -100, 900 (xmin, xmax, ymin, ymax)
#> crs : NA

And if still necessary you could get your 25 lists afterwards like so:

lapply(names(rasterList), function(x) assign(paste0("rasterList_", x), rasterList[[x]], envir = .GlobalEnv))

Created on 2022-01-05 by the reprex package (v2.0.1)

Appending a list in a loop (R)

There are four errors in your approach.

First, file.names <- dir(path, pattern =".csv") will extract just file names, without path. So, when you try to import then, read.csv() doesn't find.

Building the path

You can build the right path including paste0():

path = "~/path/to/csv/"
file.names <- paste0(path, dir(path, pattern =".csv"))

Or file.path(), which add slashes automaticaly.

path = "~/path/to/csv"
file.names <- file.path(path, dir(path, pattern =".csv"))

And another way to create the path, for me more efficient, is that suggested in the answer commented by Tung.

file.names <- list.files(path = "~/path/to/csv", recursive = TRUE,
pattern = "\\.csv$", full.names = TRUE)

This is better because in addition to being all in one step, you can use within a directory containing multiple files of various formats. The code above will match all .csv files in the folder.

Importing, selecting and creating the list

The second error is in mylist <- c(). You want a list, but this creates a vector. So, the correct is:

mylist <- list()

And the last error is inside the loop. Instead of create other list when appending, use the same object created before the loop:

for(i in 1:length(file.names)){
datatmp <- read.csv(file.names[i], sep=";", stringsAsFactors=FALSE)
listtmp = datatmp[, 6]
mylist <- append(mylist, list(listtmp))
}
mylist

Another approach, easier and cleaner, is looping with lapply(). Just this:

mylist <- lapply(file.names, function(x) {
df <- read.csv(x, sep = ";", stringsAsFactors = FALSE)
df[, 6]
})

Hope it helps!

R Access first element of the list while using loop and append it into a vector

I may have misunderstood, but is this your intended outcome?

#install.packages("seewave")
library(seewave)

klvalue<- function(a,b){kl.dist(a, b, base = exp(1))
} #kl.dist is from library(seewave)

vector1=c(1213, 57683, 74466, 44419, 17481, 3403, 42252, 7045,29445, 15004, 21337, 1892, 21861, 238, 26574, 17579)
vector2=c(3185, 29692, 12570, 26081, 4992, 1659, 16592, 1748, 37583, 6751, 10188, 355, 8116, 9, 5064, 1846)

w<-2
ab <- list()
pred <- list()
obs <- list()
count <- 1
kldta <- list()

for (i in w:length(vector1)){
pred[[count]] <- vector1[(i-w+1):i]
obs[[count]] <- vector2[(i-w+1):i]

a1 <- pred[count]
a2 <- obs[count]
count <- count + 1
klval <- klvalue(unlist(a1),unlist(a2))
kldta[i] <- klval[[1]]
}

kldta_final <- unlist(kldta)
kldta_final
#> [1] 0.0475256543 0.1523148191 0.1896899344 0.0468433690 0.0219116189
#> [6] 0.0017162112 0.0115640592 0.1471657288 0.1053351614 0.0004260342
#> [11] 0.0253701967 0.0141622162 0.0148801420 0.0072153100 0.0403388718

Created on 2022-05-31 by the reprex package (v2.0.1)



Related Topics



Leave a reply



Submit