【问题标题】:How to use assign to modify part of a vector in R?如何使用assign修改R中的部分向量?
【发布时间】:2015-02-05 00:50:10
【问题描述】:

assign 的 R 帮助说:“assign 不分派赋值方法,因此不能用于设置向量、名称、属性等元素。”往下看,在示例中,我们展示了:

a <- 1:4
assign("a[1]", 2)
a[1] == 2          # FALSE
get("a[1]") == 2   # TRUE

我想知道如何解决这个例子指出的问题——给定一个代表向量或数据框的一部分的字符串,我如何分配到那个位置?我可以获取值:

x <- "a[1]"
eval(parse(text=x))  # 1

当然我可以分配到向量的一部分

a[1:2] <- c(0,0)

如果我从字符串开始,我该如何把它们放在一起呢?


谢谢LauriK,但我的困难是字符串是“a[1:2]”,所以即使get 也会失败。我将解释让我提出这个问题的原因。

我有两个数据框,一个是这样的:

> df
  Fiscal Year  Num Deferrals  1 Yr Prob
1        2015             0        100%
2        2016             0        100%
3        2017            65         98%
2 Year Total             65         n/a
2 Year Average           32         n/a

还有一个这样的:

> sv
nDeferrals   nSmallDeferrals   oneYrProb
          0                 0      1.0000
          0                 0      1.0000
         65                63       .9797

我想保存这两个东西的部分描述,在以后的运行中,只要第一个不改变,我会用第二个的值替换它。所以我有两个字符串:

"df$'1 Yr Prob'[1:3]"
"sv$oneYrProb"

只要“df$'1 Yr Prob[1:3]”没有改变,我将用“sv$oneYrProb”在未来运行时的值覆盖它。我正在保存两个变量的名称,以及第一个变量在冻结时的值:

freeze <- function(R_name, saved_name) {
    frozen <- new.env()
    R_value <- eval(parse(text=R_name))
    with(frozen, assign(R_name, list(R_name, R_value, saved_name)))
    save(frozen, file="frozen.RData")
}

结果是“冻结”环境包含如下所示的变量:

> frozen$"df$'1 Yr Prob'[1:3]"
[[1]]
[1] "df$\"1 Yr Prob\"[1:3]"

[[2]]
[1] "100% "100%" "98%"

[[3]]
[1] "sv$oneYrProb"

所以我有代表测试中两个对象的字符串,以及第一个对象在冻结时的值。
我可以获取对象的值 - 使用“eval(parse”) - 但我不知道如何存储回第一个。我有:

processFreezeList <- function() {
    load("frozen.RData", envir=.GlobalEnv)
    variables <- ls(frozen)
    for (v in variables) {
        temp <- get(v, frozen)
        R_name <- temp[[1]]
        R_value <- temp[[2]]
        saved_name <- temp[[3]]
        if (all(eval(parse(text=R_name)) == R_value))
            assign(R_name, eval(parse(text=saved_name)), envir=.GlobalEnv)
    }
}

assign 不是覆盖第一个对象,而是创建一个新变量:

"df$/"1 Yr Prob/"[1:3]"

使用该字符串,我可以获取它所代表的值,但我不知道如何写回它们。为了解决原来的问题,我正在转向替代,但它似乎应该可以用字符串来解决。

【问题讨论】:

  • 您认为为什么需要这样做?你可能不知道。如果您使用eval()assign(),几乎总有一种“更好”、更“R-like”的方式来做事。

标签: r assign


【解决方案1】:

如果我对您的理解正确,那么您想更改向量的一部分,同时只知道向量名称作为字符串变量。试试这样的:

> (a <- letters[1:5])
[1] "a" "b" "c" "d" "e"
> x <- "a"
> var.x <- get(x)
> var.x[1:2] <- c(0,0)
> assign(x, var.x)
> a
[1] "0" "0" "c" "d" "e"

【讨论】:

  • @RichardScriven 请解释一下。我将第一行添加到我的答案中,它可以作为原始问题的答案。既然我已经看到原始问题经过大量编辑,我会在几个小时后看看它,看看我是否能想出一个更好的答案。
  • 那么您的原始答案在get(x) 中触发了一个错误,因为a 未定义。因此每次调用都会触发错误。
  • @LauriK 我还在海上。我的字符串不像“a”。它是 "a[1]" 的众多变体之一,而 get("a[1]") 不起作用。
【解决方案2】:

我对引发我的问题的问题有一个答案,我认为它可以概括。它看起来像这样:

a <- c(1,1,1)
b <- c(2,2,2)
x <- "a[1]"
y <- "b[1]"
eval(parse(text=paste(x,"<-",y)
a
[1] 2 1 1

换句话说,将赋值本身带入字符串并对其进行评估。

【讨论】:

  • @RichardScriven 我要感谢 LauriK 和 RichardScriven 帮助我解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 2016-09-28
  • 2015-04-08
  • 2014-02-08
  • 2018-07-23
  • 2013-04-23
相关资源
最近更新 更多