【问题标题】:Generating a new variable with get(data.table) directly after loading data.table object加载 data.table 对象后直接使用 get(data.table) 生成新变量
【发布时间】:2014-08-28 21:22:54
【问题描述】:

我正在尝试在我生成、保存并再次加载的 data.table 中生成一个新变量。加载后,我通过 get() 间接寻址 data.table,只要我之前不直接寻址它以创建变量,这不适用于生成新变量。 可能是某种环境问题?

# Generate data.table
t<-data.table(x=c(1,2,3,4))
tStr<-"t"
names(t)

# Generate Variable a -> ok
get(tStr)[, a:=1]
names(t)

# Generate Variable b -> ok
t[, b:=1]
names(t)

# Save
save(t, file="test.Robj")
load("test.Robj", .GlobalEnv)

# Generate Variable c -> fails 
get(tStr)[, c:=1] 
names(t)

# Generate Variable d -> ok
t[, d:=1]
names(t)

# Generate Variable e -> ok again !?
get(tStr)[, e:=1]
names(t)

感谢您的帮助

【问题讨论】:

标签: r data.table


【解决方案1】:

这是因为重要的元数据无法在存储操作中存活:

> t<-data.table(x=c(1,2,3,4))
> attr(t, ".internal.selfref")
<pointer: 0x0000000000100788>
> save(t, file="test.Robj")
> load("test.Robj", .GlobalEnv)
> attr(t, ".internal.selfref")
<pointer: (nil)>
> t[, d:=1]
> attr(t, ".internal.selfref")
<pointer: 0x0000000000100788>

注意你是如何丢失内存指针的。我不确定这与data.table 是什么和save 的功能之间的内在冲突有多大关系。似乎为了使其正常工作,我们需要一个特殊的 load 方法,在加载 data.table 对象时重新分配内部指针。

在这种情况下,使用引用修改似乎会重置指针。

编辑:作为您的用例中的一种解决方法,您可以尝试:

t <- data.table(x=c(1,2,3,4))
save(t, file="test.Robj")
load("test.Robj", .GlobalEnv)
assign("t", get("t")[, c:=3])
t

按预期工作:

   x c
1: 1 3
2: 2 3
3: 3 3
4: 4 3

还要注意期望:

get("t")[, c:=3]

会起作用有点像期待:

get("x") <- 5

会起作用。 data.table 将来可能会添加此功能,但如果您正踏入这个模糊的领域,data.table 的引用性质确实开始与 R 语义发生冲突。

【讨论】:

  • 外部指针丢失是真的。但这只是部分原因。如果你这样做:t[, c := 1] 在加载后立即起作用,因为它检测到自引用无效并纠正它(=> 浅拷贝 + 过度分配),添加新列,然后 分配新对象返回父环境t 是一个符号)。但是对于get(.)[, c := 1]分配回父环境 会稍微困难一些。这还没有完成(至少对于这个用例)。
  • @Arun,似乎想出在每种情况下都有效的东西将是一项挑战。我认为在某些时候你最终会解决 R 无引用语义(例如colnames&lt;- 等)并为这些情况提供解决方法(例如setnames)。
  • 好的,似乎比我教的更复杂,感谢 BrodieG 的解决方法,它适用于我的目的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-21
相关资源
最近更新 更多