R中的data.table不能使用dput

rns*_*nso 10 r data.table

我有以下data.table,我不能使用dput命令的输出来重新创建它:

> ddt
   Unit Anything index new
1:    A      3.4     1   1
2:    A      6.9     2   1
3:   A1      1.1     1   2
4:   A1      2.2     2   2
5:    B      2.0     1   3
6:    B      3.0     2   3
> 
> 
> str(ddt)
Classes ‘data.table’ and 'data.frame':  6 obs. of  4 variables:
 $ Unit    : Factor w/ 3 levels "A","A1","B": 1 1 2 2 3 3
 $ Anything: num  3.4 6.9 1.1 2.2 2 3
 $ index   : num  1 2 1 2 1 2
 $ new     : int  1 1 2 2 3 3
 - attr(*, ".internal.selfref")=<externalptr> 
 - attr(*, "sorted")= chr  "Unit" "Anything"
> 
> 
> dput(ddt)
structure(list(Unit = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("A", 
"A1", "B"), class = "factor"), Anything = c(3.4, 6.9, 1.1, 2.2, 
2, 3), index = c(1, 2, 1, 2, 1, 2), new = c(1L, 1L, 2L, 2L, 3L, 
3L)), .Names = c("Unit", "Anything", "index", "new"), row.names = c(NA, 
-6L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x8948f68>, sorted = c("Unit", 
"Anything"))
> 
Run Code Online (Sandbox Code Playgroud)

在粘贴时我得到以下错误:

> dt = structure(list(Unit = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("A", 
+ "A1", "B"), class = "factor"), Anything = c(3.4, 6.9, 1.1, 2.2, 
+ 2, 3), index = c(1, 2, 1, 2, 1, 2), new = c(1L, 1L, 2L, 2L, 3L, 
+ 3L)), .Names = c("Unit", "Anything", "index", "new"), row.names = c(NA, 
+ -6L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x8948f68>, sorted = c("Unit", 
Error: unexpected '<' in:
"3L)), .Names = c("Unit", "Anything", "index", "new"), row.names = c(NA, 
-6L), class = c("data.table", "data.frame"), .internal.selfref = <"
> "Anything"))
Error: unexpected ')' in ""Anything")"
Run Code Online (Sandbox Code Playgroud)

问题在哪里以及如何纠正?谢谢你的帮助.

edd*_*ddi 13

问题是dput打印出外部指针地址(这是data.table内部使用的东西,并在需要时重建),这是你无法真正使用的.

如果您手动切出.internal.selfref部件,它将正常工作,除了data.table一些操作的一次性投诉.

您可以data.table为此添加FR ,但它需要修改基本功能data.table,类似于rbind当前处理的方式.


sha*_*dow 6

我也发现这种行为相当烦人。所以我创建了自己的dput函数来忽略该.internal.selfref属性。

dput <- function (x, file = "", control = c("keepNA", "keepInteger", 
                                    "showAttributes")) 
{
  if (is.character(file)) 
    if (nzchar(file)) {
      file <- file(file, "wt")
      on.exit(close(file))
    }
  else file <- stdout()
  opts <- .deparseOpts(control)
  # adding these three lines for data.tables
  if (is.data.table(x)) {
    setattr(x, '.internal.selfref', NULL)
  }
  if (isS4(x)) {
    clx <- class(x)
    cat("new(\"", clx, "\"\n", file = file, sep = "")
    for (n in .slotNames(clx)) {
      cat("    ,", n, "= ", file = file)
      dput(slot(x, n), file = file, control = control)
    }
    cat(")\n", file = file)
    invisible()
  }
  else .Internal(dput(x, file, opts))
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么这么复杂?不只是 `dput = function(x, ...) { if(is.data.table(x)) { setattr(x, '.internal.selfref', NULL) }; base::dput(x, ...) }` 工作吗?或者也许更好,将 `is.data.table` 替换为 `inherits` (3认同)