使用"assign()"为列表项分配值 [英] Assigning a value to a list item using `assign()`

查看:132
本文介绍了使用"assign()"为列表项分配值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先要有上下文...

A little bit of context first...

我编写了一个infix函数,该函数本质上替代了惯用语

I've written an infix function that in essence replaces the idiom

x[[length(x) +1]] <- y

..或简单地按x <- append(x, y)表示向量.

..or simply x <- append(x, y) for vectors.

这里是:

`%+=%` <- function(x, y) {
  xcall <- substitute(x)
  xobjname <- setdiff(all.names(xcall), c("[[", "[", ":", "$"))
  # if the object doesn't exist, create it
  if (!exists(xobjname, parent.frame(), mode = "list") &&
      !exists(xobjname, parent.frame(), mode = "numeric") &&
      !exists(xobjname, parent.frame(), mode = "character")) {
    xobj <- subset(y, FALSE)
  } else {
    xobj <- eval(xcall, envir = parent.frame())
  }

  if (is.atomic(xobj)) {
    if (!is.atomic(y)) {
      stop('Cannot append object of mode ', dQuote(mode(y)), 
           ' to atomic structure ', xobjname)
    }
    assign(xobjname, append(xobj, y), envir = parent.frame())
    return(invisible())
  }

  if (is.list(xobj)) {
    if (is.atomic(y)) {
      xobj[[length(xobj) + 1]] <- y
    } else {
      for (i in seq_along(y)) {
        xobj[[length(xobj) + 1]] <- y[[i]]
        names(xobj)[length(xobj)] <- names(y[i])
      }
    }
    assign(xobjname, xobj, envir = parent.frame())
    return(invisible())
  }

  stop("Can't append to an object of mode ", 
       mode(eval(xcall, envir = parent.frame())))
}

它可以与vector或list一起使用,但是目前形式的限制是我不能将值附加到list内的项目上,例如:

It works as intended with vector or lists, but the limit in its present form is that I can't append a value to a item inside a list, e.g.:

a <- list(a = 1, b = 2)
a$b %+=% 3

到目前为止,我还没有找到该怎么做的方法.我已经尝试过类似以下的方法,但是没有效果:

So far I haven't found how to do it. I've tried something like the following, but it has no effect:

assign("b", append(a$b, 3), envir = as.environment(a))

有什么想法吗?

推荐答案

建议不使用分配,而是:

Suggest not using assign and instead:

`%+=%`<- function(x, value) eval.parent(substitute(x <- append(x, value)))

x <- 3
x %+=% 5
x
## [1] 3 5

L <- list(a = 1, b = 2)
L %+=% 3
## List of 3
## $ a: num 1
## $ b: num 2
## $  : num 3

L <- list(a = 1, b = 2)
L$a %+=% 4
str(L)
## List of 2
##  $ a: num [1:2] 1 4
##  $ b: num 2

或尝试使用+ <-语法,避免使用eval:

`+<-` <- append

# test
x <- 3
+x <- 1
x
## [1] 3 1

# test
L<- list(a = 1, b = 2)
+L <- 10
str(L)
## List of 3
##  $ a: num 1
##  $ b: num 2
##  $  : num 10

# test
L <- list(a = 1, b = 2)
+L$a <- 10
str(L)
## List of 2
##  $ a: num [1:2] 1 10
##  $ b: num 2

或尝试使用与+<-类似的替换函数语法.

Or try this replacement function syntax which is similar to +<-.

`append<-` <- append
x <- 3
append(x) <- 7
## [1] 3 7

... etc ...

这篇关于使用"assign()"为列表项分配值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆