在R中推送和弹出列表的更好方法是什么?

log*_*thy 9 r

如果foo <- list(),foo[[length(foo)+1]] <- bar当我真正想写的时候,我发现自己写了很多东西push(foo, bar).

同样地(尽管不那么频繁)bar <- foo[[length(foo)]]会更好bar <- pop(foo).

  1. 在基地R有更好的方法吗?
  2. 如果不这样做,是否有人编写了一个使这些基本列表操作在语法上更少折磨的包?

这是重复的变量名称杀死了我.考虑:

anInformative.selfDocumenting.listName[[length(anInformative.selfDocumenting.listName)+1]] <- bar
Run Code Online (Sandbox Code Playgroud)

编辑:

foo <- append(foo, bar) 不适合我

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo[[length(foo)+1]] <- x
}
str(foo)
Run Code Online (Sandbox Code Playgroud)

按预期提供10个对象的列表.

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo <- append(foo, x)
}
str(foo)
Run Code Online (Sandbox Code Playgroud)

给出了20个对象的列表.

MrF*_*ick 12

foo[[length(foo)+1]] <- bar
Run Code Online (Sandbox Code Playgroud)

可以改写为

foo <- append(foo, bar)
Run Code Online (Sandbox Code Playgroud)

bar <- foo[[length(foo)]]
Run Code Online (Sandbox Code Playgroud)

可以改写为

bar <- tail(foo,1)
Run Code Online (Sandbox Code Playgroud)

请注意,使用R函数等函数语言通常不会更改传递给它们的参数值; 通常你会返回一个可以在别处分配的新对象.该功能应该没有"副作用".像push/pop其他语言一样的函数通常会修改其中一个传递的参数.

  • 好吧,你没有提到你使用的是data.frames.试试`foo < - append(foo,list(x))`.但实际上,您的示例看起来应该使用`lapply()`或其他一些函数.在for循环中逐个添加元素是非常低效的.例如:`foo <-lapply(1:10,function(i)data.frame(a = i,b = rnorm(1,0,1))) (2认同)
  • 是的,逐个添加元素的代码通常比较慢,因为随着集合的增长,您需要不断重新分配内存。使用 lapply 一次生成所有列表会更好,因为 R 将知道新对象的总长度并且只为它分配一次内存。 (2认同)

Chr*_*ian 3

晚了几年,但这是需要最少打字量的方法。请注意,这pop会从对象中删除最后一个元素。

push <- function(obj, input) {
  variable <- deparse(substitute(obj))
  out <- get(variable, envir = parent.frame(n=2))
  out[[length(out)+1]] <- input
  assign(variable, out, envir = parent.frame(n=2))
}

pop <- function(obj) {
  variable <- deparse(substitute(obj))
  obj <- get(variable, envir = parent.frame(n=2))
  
  if (length(obj) > 0) {
    out <- obj[[length(obj)]]
    assign(variable, obj[-length(obj)], envir = parent.frame(n=2))
  }else{
    out <- NULL
    assign(variable, out, envir = parent.frame(n=2))
  }
  
  return(out)
}
Run Code Online (Sandbox Code Playgroud)

例子:

> foo <- list()
> push(foo, "a")
> push(foo, "b")
> foo
[[1]]
[1] "a"

[[2]]
[1] "b"

> pop(foo)
[1] "b"
> foo
[[1]]
[1] "a"
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的答案,对于像我这样来自 Python 的人特别有帮助。这不是一个内置函数,这似乎有点奇怪。 (3认同)