向 R 中的空向量追加值? ?

我想学 R 但是我不知道怎么加到列表里。

如果这是巨蟒,我会. 。

#Python
vector = []
values = ['a','b','c','d','e','f','g']


for i in range(0,len(values)):
vector.append(values[i])

你怎么在 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
638403 次浏览

你有几个选择:

  • c(vector, values)

  • append(vector, values)

  • vector[(length(vector) + 1):(length(vector) + length(values))] <- values

第一种是标准方法。第二个选项提供了在结尾之外添加其他内容的选项。最后一个是有点扭曲,但有修改 vector的优势(虽然真的,你可以很容易地做 vector <- c(vector, values)

注意,在 R 中你不需要循环遍历向量,你只需要对它们进行整体操作。

此外,这是相当基本的东西,所以您应该通过一些 译自: 美国《科学》杂志网站(http://stackoverflow. com/tag/r/info)

基于 OP 反馈的更多选项:

for(i in values) vector <- c(vector, i)

在 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")可以回答你的问题,节省你写这个问题的时间(但会导致你养成坏习惯)。;-)

注意,vector <- c()不是一个空向量,它是 NULL。如果你想要一个空字符向量,使用 vector <- character()

在循环之前预先分配向量

如果 必须的使用 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

FWIW: 类似于 python 的 append () :

b <- 1
b <- c(b, 2)

正如@BrodieG 指出的那样,仅仅为了完整性,在 for 循环中向向量添加值并不是 R R 中的哲学,通过对向量作为一个整体进行操作,可以更好地工作。看看你的代码是否能被重写为:

ouput <- sapply(values, function(v) return(2*v))

输出将是返回值的向量。如果值是列表而不是向量,也可以使用 lapply

在 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"
> 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"

有时我们必须使用循环,例如,当我们不知道需要多少次迭代才能得到结果时。以 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

这是非常低效的,因为 R 在每次向量附加时都会复制它。

最有效的附加方法是使用 index。注意,这次我让它迭代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

这是可以接受的。我们可以使它更快一点,取代 [[[

a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[[length(a)+1]]=pi
}
}
)
# user  system elapsed
# 5.29    0.38    5.69

也许你已经注意到了 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

正如其他用户提到的,预先分配向量是非常有帮助的。但是如果您不知道需要多少个循环才能得到结果,那么这就是速度和内存使用之间的权衡。

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

一种中间方法是逐步添加结果块。

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

你在 python 代码中使用的是 python 中的 list 它和 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))