我在理解传递的引用属性方面遇到了一些麻烦data.table
.有些操作似乎"打破"了参考,我想准确理解发生了什么.
在data.table
从另一个创建a 时data.table
(通过<-
,然后更新新表:=
,原始表也会被更改.这是预期的,按照:
?data.table::copy
和stackoverflow:传递引用操作在数据表包中
这是一个例子:
library(data.table)
DT <- data.table(a=c(1,2), b=c(11,12))
print(DT)
# a b
# [1,] 1 11
# [2,] 2 12
newDT <- DT # reference, not copy
newDT[1, a := 100] # modify new DT
print(DT) # DT is modified too.
# a b
# [1,] 100 11
# [2,] 2 12
Run Code Online (Sandbox Code Playgroud)
但是,如果我:=
在<-
赋值和:=
上面的行之间插入非基础修改,DT
现在不再修改:
DT = data.table(a=c(1,2), b=c(11,12))
newDT …
Run Code Online (Sandbox Code Playgroud) 我想复制已从*.csv文件读入的数据框的全部内容.如果我这样做,我不相信这是重复copyOfFirstFrame <- firstFrame
.那么我需要做什么?
firstFrame <- read_csv("fileName.csv")
copyOfFirstFrame <- ?????
Run Code Online (Sandbox Code Playgroud)
如果我执行以下操作,则内存地址保持不变.
copyOfFirstFrame <- firstFrame
tracemem(firstFrame) == tracemem(copyOfFirstFrame)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
副本必须产生两个唯一的内存地址.Check In R,我如何检查两个变量名是否引用相同的底层对象?详情.
基于这个答案,我了解了一类可以从R访问的特殊内部函数:通过访问的一组函数.Internal(specialFunction)
.如果有人查询,?.Internal
可能会发现以下摘录:
只有真正的R向导才应该考虑使用此函数,只有R开发人员才能添加到内部函数列表中.
我想为我的OWL有趣的R功能掌握魔药和防御暗黑艺术.R向导在哪里可以找到内部函数的列表和描述? 只要它不涉及分裂我的灵魂.
我从Matlab那里得到了一个条件调试标志:dbstop if infnan
这里描述.如果设置,此条件将在遇到Inf
或NaN
遇到时停止代码执行(IIRC,Matlab没有NA).
如何在R中以比在每次赋值操作后测试所有对象更有效的方式实现此目的?
目前,我认为这样做的唯一方法是通过以下方式进行黑客攻击:
is.finite()
,在这个问答描述,每一个元件上.body()
修改代码来调用一个单独的功能,每一个操作或者可能只是每个任务,测试所有对象(也可能在所有环境中的所有对象)之后.tracemem
标识已更改的变量,并仅检查这些变量是否为错误值.第一个选项是我目前正在做的事情.这很乏味,因为我无法保证我已经检查过所有内容.第二个选项将测试所有内容,即使对象尚未更新.这是浪费大量时间.第3个选项将涉及修改NA,NaN和无限值(+/- Inf)的赋值,以便产生错误.这似乎最好留给R Core.第四个选项就像第二个选项 - 我需要调用一个单独的函数列出所有内存位置,只需要识别那些已更改的ID,然后检查值; 我甚至不确定它是否适用于所有对象,因为程序可能会进行就地修改,这似乎不会调用该duplicate
函数.
我错过了更好的方法吗?也许Mark Bravington,Luke Tierney的一些聪明的工具,或者相对基本的东西 - options()
在编译R时类似于参数或标志?
示例代码下面是一些非常简单的示例代码,可以使用addTaskCallback
Josh O'Brien提出的函数进行测试.代码不会中断,但在第一种情况下确实会发生错误,而在第二种情况下不会发生错误(即badDiv(0,0,FALSE)
不会中止).我还在调查回调,因为这看起来很有希望.
badDiv <- function(x, y, flag){
z = x / y
if(flag == TRUE){
return(z)
} else {
return(FALSE)
}
}
addTaskCallback(stopOnNaNs)
badDiv(0, 0, TRUE)
addTaskCallback(stopOnNaNs)
badDiv(0, 0, FALSE)
Run Code Online (Sandbox Code Playgroud)
注意1.我对标准R操作的解决方案感到满意,尽管我的很多计算涉及通过data.table
或使用的对象bigmemory …
让我们抓住环境"命名空间:统计数据"和"包:统计数据"
ns = getNamespace( "stats" )
pkg = as.environment( "package:stats" )
Run Code Online (Sandbox Code Playgroud)
现在让我们在两者中获得"sd"函数:
nsSd = get( "sd" , envir = ns , inherits = FALSE )
pkgSd = get( "sd" , envir = pkg , inherits = FALSE )
Run Code Online (Sandbox Code Playgroud)
它们是一样的吗?他们是!但"同样"是什么意思呢?参考或价值平等?
identical( nsSd , pkgSd )
Run Code Online (Sandbox Code Playgroud)
这意味着引用相等,因为以下返回FALSE:
test1 = function() {}
test2 = function() {}
identical( test1 , test2 )
Run Code Online (Sandbox Code Playgroud)
但如果这是真的,那就意味着Environment的框架可以包含函数指针和函数对象.使问题进一步复杂化的是,函数可以在一个环境中"生存",但可以告诉函数其执行环境是另一个环境.钱伯斯SoDA似乎没有答案(它是一本密集的书,也许我错过了!)
所以,我想要一个明确的答案.以下哪项是正确的?或者这里是否有错误的三分法?
nsSd
并且pkgSd
是两个不同的对象(尽管是彼此的副本),其中对象pkgSd
具有ns
作为其执行环境nsSd
并pkgSd
指向同一个对象. nsSd
是一个指针,pkgSd
因此它们被视为相同r ×5
conditional ×1
copy ×1
data.table ×1
dataframe ×1
debugging ×1
internals ×1
nan ×1
reference ×1