Append value to empty vector in R?
Appending to an object in a for loop causes the entire object to be copied on every iteration, which causes a lot of people to say "R is slow", or "R loops should be avoided".
As BrodieG mentioned in the comments: it is much better to pre-allocate a vector of the desired length, then set the element values in the loop.
Here are several ways to append values to a vector. All of them are discouraged.
Appending to a vector in a loop
# one way
for (i in 1:length(values))
vector[i] <- values[i]
# another way
for (i in 1:length(values))
vector <- c(vector, values[i])
# yet another way?!?
for (v in values)
vector <- c(vector, v)
# ... more ways
help("append")
would have answered your question and saved the time it took you to write this question (but would have caused you to develop bad habits). ;-)
Note that vector <- c()
isn't an empty vector; it's NULL
. If you want an empty character vector, use vector <- character()
.
Pre-allocate the vector before looping
If you absolutely must use a for loop, you should pre-allocate the entire vector before the loop. This will be much faster than appending for larger vectors.
set.seed(21)
values <- sample(letters, 1e4, TRUE)
vector <- character(0)
# slow
system.time( for (i in 1:length(values)) vector[i] <- values[i] )
# user system elapsed
# 0.340 0.000 0.343
vector <- character(length(values))
# fast(er)
system.time( for (i in 1:length(values)) vector[i] <- values[i] )
# user system elapsed
# 0.024 0.000 0.023
Cannot create an empty vector and append new elements in R
append
does something that is somewhat different from what you are thinking. See ?append
.
In particular, note that append
does not modify its argument. It returns the result.
You want the function c
:
> a <- numeric()
> a <- c(a, 1)
> a
[1] 1
Do something then append that value do an empty vector
There are a few ways of doing this. If you want to use a loop, the trick is to define an empty vector before initiating the loop, and store values in that. Here's an example using rnorm
to generate values from a standard normal, since I don't have the code for your rnormout
function:
M <- 1000
means <- vector()
for (i in 1:M){
means[i] = mean(rnorm(100, 0, 1))
}
Alternatively, it's better not to use a for loop at all. You can use map_dbl
to replace the loop in one line:
library(tidyverse)
M <- 1000
means <- map_dbl(1:M, ~ mean(rnorm(100, 0, 1)))
How to append an empty array in R
We need to assign (<-
) to 'values' to update the original object
for (n1 in 1:50) {
n2 = n1+1
temp_val = (n1+n2)
values <- append(values,temp_val)
}
-output
values
#[1] 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67
#[34] 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101
How do I append to a vector using a `while` loop?
Try this:
vec_teamCodes <- c()
x <- 0
while (x < 10) {
vec_teamCodes <- c(vec_teamCodes,"Hello")
# OR
# vec_teamCodes <- append(vec_teamCodes,"Hello")
x <- x+1
}
[1] "Hello" "Hello" "Hello" "Hello" "Hello" "Hello" "Hello" "Hello" "Hello" "Hello"
How do I create an empty vector in r?
There are several ways to create empty vector in r. For example,
v2<-NULL
or
v2<-c()
Try this:
v2 <- NULL
for (i in 1:length(df)){
if (df$Texture[i] == 'Silt Loam'){
new_val <- df$`pH 1:1`[i]}
v2[i] <- new_val
}
how to append an element to a list without keeping track of the index?
There is a function called append
:
ans <- list()
for (i in 1992:1994){
n <- 1 #whatever the function is
ans <- append(ans, n)
}
ans
## [[1]]
## [1] 1
##
## [[2]]
## [1] 1
##
## [[3]]
## [1] 1
##
Note: Using apply
functions instead of a for loop is better (not necessarily faster) but it depends on the actual purpose of your loop.
Answering OP's comment: About using ggplot2
and saving plots to a list, something like this would be more efficient:
plotlist <- lapply(seq(2,4), function(i) {
require(ggplot2)
dat <- mtcars[mtcars$cyl == 2 * i,]
ggplot() + geom_point(data = dat ,aes(x=cyl,y=mpg))
})
Thanks to @Wen for sharing Comparison of c()
and append()
functions:
Concatenation (c) is pretty fast, but append is even faster and therefor preferable when concatenating just two vectors.
Appending a vector in R
You need to use <<-
instead of <-
.
The operator <<-
is normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned.
fun <- function() {
s <- sample(a, 1)
b <<- c(b,s)
print(paste("Sample:", s))
print(paste("Selected so far:",b))
}
fun()
#[1] "Sample: 7"
#[1] "Selected so far: 7"
fun()
#[1] "Sample: 3"
#[1] "Selected so far: 7" "Selected so far: 3"
Append value to vector if condition met in other column
You can do :
#Remove last 2 rows
tmp <- head(df, -2)
#Get the corresponding value of HOD where TEST = 1
v <- as.numeric(tmp$HOD[tmp$TEST == 1])
v
#[1] 1.30 8.00 1.36
Related Topics
Split Code Over Multiple Lines in an R Script
Add a "Rank" Column to a Data Frame
Lib Unspecified & Error in Loadnamespace
Assign Intermediate Output to Temp Variable as Part of Dplyr Pipeline
Geometric Mean: Is There a Built-In
Extend Contigency Table with Proportions (Percentages)
Concatenate Strings and Expressions in a Plot's Title
R-Project No Applicable Method For 'Meta' Applied to an Object of Class "Character"
Ggplot2 Pie and Donut Chart on Same Plot
The Cause of "Bad Magic Number" Error When Loading a Workspace and How to Avoid It
Add "Filename" Column to Table as Multiple Files Are Read and Bound
How to Geocode a Simple Address Using Data Science Toolbox