【问题标题】:R - interesting issue with either data frame or global variableR - 数据框或全局变量的有趣问题
【发布时间】:2013-11-01 19:33:11
【问题描述】:

看看这段代码。我正在尝试制作以只有 ID 的空数据框开头并动态添加数据的代码。例如,假设它以

开头
  ID
1  1
2  2
3  3

然后我打个电话

addPair(1,"a",4); #sets the value of column "a" at row 1 to be the value 4

会变成

ID    a
1  1  4
2  2  NA
3  3  NA

看看下面的这段代码。 期望的最终total变量是:

ID   a  
1  1 4  
2  2 NA
3  3 NA 

但最后,total 只是

  ID
1  1
2  2
3  3

这里是代码。为什么total 不保留它添加的内容?在方法结束时,total 是正确的,但是在方法之后,total 又回到了IDs。这是代码,下面是输出。

# rm(list=ls())  # that code _should_ always be commented out

#get all the IDs
IDs = c("1","2","3")
N = length(IDs)

#the big data frame
total <- data.frame("ID"=IDs)

addPair = function(i,name,val) {
    total[,toString(name)] = rep(NA,N)
    total[,toString(name)][i] = val
    print("end")
    print(total)
}

addPair(1,"a",4)
print("after call")
print(total)

这是输出:

[1] "end"
  ID  a
1  1  4
2  2 NA
3  3 NA
> print("after call")
[1] "after call"
> print(total)
  ID
1  1
2  2
3  3

为什么total在方法结束后会丢失a那一列?

【问题讨论】:

  • 因为在 R 中,发生在维加斯的事情会留在维加斯(除非你告诉别人)。现在用“功能”替换“拉斯维加斯”。函数中发生的一切都发生在函数创建的环境中,然后在退出函数时将其丢弃。
  • addPair 只需要一个单列数据框,对其进行操作并显示发生了什么操作;什么都没有被保存。一个快速的解决方法是使用&lt;&lt;- 而不是= 来更改total 并将其保存在您的.GlobalEnv 中。
  • 可能更令您惊讶的是,当您的函数运行total[,toString(name)] = rep(NA,N) 行时,它首先实际上将total 复制 total 到函数中的本地环境中,然后然后修改 that.
  • 不要听@alexis_laz。 &lt;&lt;- 的使用是希望 R 像 SAS 或 BASIC 的人的警钟。避免快速修复的花言巧语,并学习使用$&lt;- 作为目标数据框中新列的分配。或者学习使用transform,您似乎正在尝试重新发明。
  • @DWin:我同意“小心&lt;&lt;-”,但我认为这根本没有用。如果你知道 where 你有 what,你可以让它按预期工作。事实上,我可能会说最好看看&lt;&lt;- 可以产生什么问题并深入研究环境和范围,而不是仅仅使用R 的“经典”函数,如transform(或subset)即使在他们的help() 页面中也有警告。不过,我喜欢荷马式的评论! ;)

标签: r list dataframe


【解决方案1】:
transform(total, a = {b=rep(NA,N); b[1] <- 4;b })
  ID  a
1  1  4
2  2 NA
3  3 NA

返回所需的对象,但它不会更改 total,除非您将值分配给该名称。

 addPair <- function(df,item,name, val) transform(
                         df, name={t=rep(NA,nrow(df)); t[item]=val;t} )
 addPair(total, 1,"a",4)
  ID name
1  1    4
2  2   NA
3  3   NA

> total <- addPair(total, 1,"a",4)
> total
  ID name
1  1    4
2  2   NA
3  3   NA

不幸的是,当使用with 时,transform 更多地是为控制台使用而设计的,而不是编程。编码使用并不完全安全。

【讨论】:

    猜你喜欢
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多