【问题标题】:How to avoid <<- by using assign如何通过使用assign来避免<<-
【发布时间】:2012-03-16 01:30:46
【问题描述】:

我有两段我经常使用的代码,其中我使用&lt;&lt;- 从函数中分配给全局环境。我知道我应该使用assign,因为它可以提供更好的控制并且更可预测。我正在尝试使用 assign 来解决问题,但无法将 &lt;&lt;- 代码转换为使用 assign 的代码:

一个伪造的数据集和两段带有&lt;&lt;-的代码

#CREATE A FAKE DATA SET
df <- data.frame(
    x.2=rnorm(25),
    y.2=rnorm(25),
    g=rep(factor(LETTERS[1:5]), 5)
)
#Use split to make a list of data frames
LIST <- split(df, df$g) #split it into a list of data frames
NAMES <- names(LIST) #save the names of this for later use 
LIST <- lapply(seq_along(LIST), function(x) as.data.frame(LIST[[x]])[, 1:2])

#THE TWO PIECES OF CODE THAT USE <<-
#Use Global Assignment to Change All Variable Names of Data Frames in a List
lapply(seq_along(LIST), function(x) names(LIST[[x]]) <<-
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
    ".", fixed=T))[c(T, F)]
)
LIST

#Rename All the Data Frames in the List Using Global Assignment
lapply(seq_along(LIST), function(x) names(LIST)[[x]] <<- NAMES[x])
LIST

我尝试使用 assign:

lapply(seq_along(LIST), function(x) {
    assign(names(LIST[[x]]), 
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
    ".", fixed=T))[c(T, F)],  envir=.GlobalEnv)
    }
)
LIST

lapply(seq_along(LIST), function(x) assign(names(LIST)[[x]], 
    NAMES[x], envir=.GlobalEnv))
LIST

请帮助我正确地做到这一点,并解释我的方法有什么问题。提前谢谢你。

【问题讨论】:

  • 对象名称在环境中不是name,因此您不能在此处使用assign
  • @kohske 谢谢。那你能不能给出答案,我会接受吗?

标签: r


【解决方案1】:

我不明白你为什么把这个任务弄得这么复杂。这不就是:

LIST <- df[, 1:2]
names(LIST) <- sapply(strsplit(names(LIST), '.', fixed = TRUE), `[`, 1)
LIST <- split(LIST, df$g)

即你想要df 的前两列;您想要. 之前的名称,然后拆分数据框。重新组织您的任务,您将对问题有更清晰的认识。

顺便说一句,&lt;&lt;- 不一定是可怕的动物;您可以通过在顶级环境中创建变量名称来非常安全地使用它,例如

x <- 0
f <- function() x <<- 1

只有在任何地方都没有创建变量名时才会存在危险,因此 R 必须一直到全局环境,这通常是一种非常糟糕的做法。

【讨论】:

  • 请忽略可重现的数据。这只是为了解决我的任务中出现的问题。您的解决方案仅在数据如此简单且从数据框创建且split 并非如此时才有效。 GSee很好地回答了这个问题。 +1 获取有关全局分配的信息。
【解决方案2】:

我认为这是同一件事

LIST <- lapply(seq_along(LIST), function(x) {
  names(LIST[[x]]) <- 
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
                    ".", fixed=T))[c(T, F)]
  LIST[[x]]
})
LIST

names(LIST) <- NAMES
LIST

或者,使用分配

assign("LIST", lapply(seq_along(LIST), function(x) {
  names(LIST[[x]]) <- 
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
                    ".", fixed=T))[c(T, F)]
  LIST[[x]]
}), pos=.GlobalEnv)

【讨论】:

  • 我喜欢它,因为我根本不必使用assign&lt;&lt;-
猜你喜欢
  • 1970-01-01
  • 2020-10-14
  • 2019-11-09
  • 2021-12-07
  • 1970-01-01
  • 2019-11-17
  • 2020-08-03
  • 1970-01-01
  • 2011-11-11
相关资源
最近更新 更多