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