我不太清楚为什么数据框对象不会更新
d <- data.frame(titi=c(0))
(function(dataset) {
dataset[["toto"]] <- 1;
print(names(dataset)) #has "toto" and "titi"
})(d)
print(names(d)) # no has "toto", only "titi"
Run Code Online (Sandbox Code Playgroud)
这里发生了什么 ?
我有一个解决方法,因为在我的代码中我也捕获变量并更新捕获的<<-,但我想知道机制.
我知道一般的变异等危险.我只是不明白这里的机制.
编辑
虽然这似乎是一个共识,这是一个语言级别的功能,我不遵循这个论点,好像我使用一个紧密的结构,数据表,它可以变异:
d <- data.table(titi=c(0))
(function(dataset) {
dataset[,toto:=1]
print(names(dataset)) #"titi" "toto"
})(d)
print(names(d)) #"titi" "toto"
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
您还没有阅读过R的介绍,特别是关于函数中的赋值部分或编写自己的函数的部分
两个相关的引用是
请注意,在函数内完成的任何普通赋值都是本地和临时的,并在退出函数后丢失.
和
表达式的值是为函数返回的值.
在你的情况下,函数调用的最终值names将返回一个字符向量....
范围界定可能是一个复杂的问题,但您的示例是一个简单的案例.
如果您想要更完整的参考,请查看R语言定义.
data.table它......是的,:=在data.table通过参考受让人.这不是普通的任务.
data.table继承自data.frame.它们不相同,并:=通过引用分配(也setattr)通过引用分配.这与标准R习语不符.这也可能导致问题,为什么data.table通过引用更新名称(DT),即使我分配给另一个变量?
还有其他方法,但标准的R习惯是函数中的普通赋值是本地的和临时的,并在退出后丢失.
你也可以考虑使用ReferenceClasses(见?setRefClass)
它不仅限于列表/ data.frames.原子载体是相同的
mydf <- data.frame(a=1)
mylist <- list(a=1)
mynumeric <- c(a = 1)
mydf <- data.frame(a=1)
mylist <- list(a=1)
mynumeric <- c(a = 1)
foo <- function(x){x[['b']] <- 1; print(names(x))}
# data.frame
foo(mydf)
# [1] "a" "b"
mydf
# a
# 1 1
# list
foo(mylist)
# [1] "a" "b"
mylist
# $a
# [1] 1
# atomic
foo(mynumeric)
# [1] "a" "b"
mynumeric
# a
# 1
Run Code Online (Sandbox Code Playgroud)