list 将值附加到 R 中的空向量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22235809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Append value to empty vector in R?
提问by O.rka
I'm trying to learn R and I can't figure out how to append to a list.
我正在尝试学习 R,但我不知道如何附加到列表中。
If this were Python I would . . .
如果这是 Python,我会。. .
#Python
vector = []
values = ['a','b','c','d','e','f','g']
for i in range(0,len(values)):
vector.append(values[i])
How do you do this in R?
你如何在 R 中做到这一点?
#R Programming
> vector = c()
> values = c('a','b','c','d','e','f','g')
> for (i in 1:length(values))
+ #append value[i] to empty vector
回答by Joshua Ulrich
Here are several ways to do it. All of them are discouraged. 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".
这里有几种方法可以做到。他们都感到气馁。在 for 循环中附加到一个对象会导致在每次迭代时复制整个对象,这导致很多人说“R 很慢”或“应该避免 R 循环”。
# 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). ;-)
help("append")
会回答你的问题并节省你写这个问题的时间(但会导致你养成坏习惯)。;-)
Note that vector <- c()
isn't an empty vector; it's NULL
. If you want an empty character vector, use vector <- character()
.
请注意,这vector <- c()
不是一个空向量;它是NULL
。如果您想要一个空的字符向量,请使用vector <- character()
.
Also note, as BrodieGpointed out in the comments: if you absolutely mustuse a for loop, then at least pre-allocate the entire vector before the loop. This will be much faster than appending for larger vectors.
另请注意,正如BrodieG在评论中指出的那样:如果您绝对必须使用 for 循环,那么至少在循环之前预先分配整个向量。这将比附加更大的向量快得多。
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
回答by tumultous_rooster
FWIW: analogous to python's append():
FWIW:类似于 python 的 append():
b <- 1
b <- c(b, 2)
回答by BrodieG
You have a few options:
您有几个选择:
c(vector, values)
append(vector, values)
vector[(length(vector) + 1):(length(vector) + length(values))] <- values
c(vector, values)
append(vector, values)
vector[(length(vector) + 1):(length(vector) + length(values))] <- values
The first one is the standard approach. The second one gives you the option to append someplace other than the end. The last one is a bit contorted but has the advantage of modifying vector
(though really, you could just as easily do vector <- c(vector, values)
.
第一个是标准方法。第二个使您可以选择在末尾以外的地方附加。最后一个有点扭曲,但具有修改的优势vector
(尽管实际上,您可以轻松地将vector <- c(vector, values)
.
Notice that in R you don't need to cycle through vectors. You can just operate on them in whole.
请注意,在 R 中,您不需要循环遍历向量。您可以对它们进行整体操作。
Also, this is fairly basic stuff, so you should go through some of the references.
此外,这是相当基本的东西,所以你应该阅读一些参考资料。
Some more options based on OP feedback:
基于 OP 反馈的更多选项:
for(i in values) vector <- c(vector, i)
回答by antoine
Just for the sake of completeness, appending values to a vector in a for loop is not really the philosophy in R. R works better by operating on vectors as a whole, as @BrodieG pointed out. See if your code can't be rewritten as:
只是为了完整起见,在 for 循环中将值附加到向量并不是 R 中真正的哲学。正如@BrodieG 指出的那样,R 通过对向量进行整体操作来更好地工作。看看你的代码是否不能重写为:
ouput <- sapply(values, function(v) return(2*v))
Output will be a vector of return values. You can also use lapply
if values is a list instead of a vector.
输出将是返回值的向量。您还可以使用lapply
if values 是列表而不是向量。
回答by user2923419
Sometimes we have to use loops, for example, when we don't know how many iterations we need to get the result. Take while loops as an example. Below are methods you absolutely should avoid:
有时我们不得不使用循环,例如,当我们不知道需要多少次迭代才能得到结果时。以while循环为例。以下是您绝对应该避免的方法:
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-c(a,pi)
}
}
)
# user system elapsed
# 13.2 0.0 13.2
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-append(a,pi)
}
}
)
# user system elapsed
# 11.06 5.72 16.84
These are very inefficient because R copies the vector every time it appends.
这些是非常低效的,因为 R 每次追加时都会复制向量。
The most efficient way to append is to use index. Note that this time I let it iterate 1e7 times, but it's still much faster than c
.
最有效的追加方式是使用索引。请注意,这次我让它迭代了 1e7 次,但它仍然比c
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[length(a)+1]=pi
}
}
)
# user system elapsed
# 5.71 0.39 6.12
This is acceptable. And we can make it a bit faster by replacing [
with [[
.
这是可以接受的。我们可以通过替换[
为[[
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[[length(a)+1]]=pi
}
}
)
# user system elapsed
# 5.29 0.38 5.69
Maybe you already noticed that length
can be time consuming. If we replace length
with a counter:
也许您已经注意到这length
可能很耗时。如果我们length
用计数器替换:
a=numeric(0)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
}
)
# user system elapsed
# 3.35 0.41 3.76
As other users mentioned, pre-allocating the vector is very helpful. But this is a trade-off between speed and memory usage if you don't know how many loops you need to get the result.
正如其他用户所提到的,预先分配向量非常有帮助。但如果您不知道需要多少循环才能获得结果,那么这是速度和内存使用之间的权衡。
a=rep(NaN,2*1e7)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
a=a[!is.na(a)]
}
)
# user system elapsed
# 1.57 0.06 1.63
An intermediate method is to gradually add blocks of results.
一种中间方法是逐渐添加结果块。
a=numeric(0)
b=0
step_count=0
step=1e6
system.time(
{
repeat{
a_step=rep(NaN,step)
for(i in seq_len(step)){
b=b+1
a_step[[i]]=pi
if(b>=1e7){
a_step=a_step[1:i]
break
}
}
a[(step_count*step+1):b]=a_step
if(b>=1e7) break
step_count=step_count+1
}
}
)
#user system elapsed
#1.71 0.17 1.89
回答by Sowmya S. Manian
In R, you can try out this way:
在 R 中,您可以这样尝试:
X = NULL
X
# NULL
values = letters[1:10]
values
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
X = append(X,values)
X
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
X = append(X,letters[23:26])
X
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "w" "x" "y" "z"
回答by Surya
> vec <- c(letters[1:3]) # vec <- c("a","b","c") ; or just empty vector: vec <- c()
> values<- c(1,2,3)
> for (i in 1:length(values)){
print(paste("length of vec", length(vec)));
vec[length(vec)+1] <- values[i] #Appends value at the end of vector
}
[1] "length of vec 3"
[1] "length of vec 4"
[1] "length of vec 5"
> vec
[1] "a" "b" "c" "1" "2" "3"
回答by Youssef Snoussi
What you're using in the python code is called a list in python, and it's tottaly different from R vectors, if i get what you wanna do:
你在 python 代码中使用的在 python 中被称为列表,它与 R 向量完全不同,如果我得到你想要做的:
# you can do like this if you'll put them manually
v <- c("a", "b", "c")
# if your values are in a list
v <- as.vector(your_list)
# if you just need to append
v <- append(v, value, after=length(v))