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
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).
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
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"
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!
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)
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.
Add plot to list using a for loop
This is the solution I came up with. I created a name for the graph based off the column name and used this to add to the list.
# Plot the data and add to list
bplot_list <- list()
for (data in dataList){
chemElement <- colnames(data[5])
p <-
data %>%
ggplot(aes_string(x='Month', y=data[,5])) +
geom_boxplot() +
theme_classic() +
labs(y= chemElement) +
scale_x_discrete()
bplot_list[[chemElement]] <- p
}
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).
Related Topics
Convert Factor to Integer in a Data Frame
(Igraph) Grouped Layout Based on Attribute
How to Detect Free Variable Names in R Functions
How to Generalize Outer to N Dimensions
How to Combine Scales for Colour and Size into One Legend
R V3.4.0-2 Unable to Find Libgfortran.So.3 on Arch
R: Sample() Command Subject to a Constraint
R * Not Meaningful for Factors Error
How to Append a Whole Dataframe to a CSV in R
Ggplot2: Drop Unused Factors in a Faceted Bar Plot But Not Have Differing Bar Widths Between Facets
R: Using a String as an Argument to Mutate Verb in Dplyr
Ggplot2: Reorder Bars from Highest to Lowest in Each Facet
Reshape Multiple Categorical Variables to Binary Response Variables
How to Find the Indices of the Top 10,000 Elements in a Symmetric Matrix(12K X 12K) in R
Ggplot X-Axis Labels with All X-Axis Values