无法对R中的data.table使用dput

无法对R中的data.table使用dput,r,data.table,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 > > >

我有以下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"))
> 
滴滴涕 有什么新的吗 1:A 3.4 1 2:A 6.92 1 3:A1 1.1 2 4:A1 2.2 5:B2.013 6:B3.023 > > >str(滴滴涕) 类“data.table”和“data.frame”:6个obs。共有4个变量: $单位:系数w/3级“A”、“A1”、“B”:1 2 3 $Anything:num 3.46.91.12.23 $index:num 12 $new:int 1 12 2 3 3 -属性(*,“.internal.selfref”)= -属性(*,“排序”)=chr“单位”“任何” > > >滴滴涕 结构(列表)(单位=结构(c(1L,1L,2L,2L,3L,3L),.Label=c(“A”), “A1”、“B”、class=“factor”、Anything=c(3.4、6.9、1.1、2.2、, 指数=c(1,2,1,2,1,2),新指数=c(1L,1L,2L,2L,2L,3L, 3L)),.Names=c(“单位”、“任何”、“索引”、“新”),row.Names=c(NA, -6L),class=c(“数据表”、“数据帧”),.internal.selfref=,sorted=c(“单位”), “任何事”)) > 粘贴时出现以下错误:

> 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")"
>dt=结构(列表(单元=结构)(c(1L,1L,2L,2L,3L,3L),.Label=c(“A”),
+“A1”、“B”、class=“factor”、Anything=c(3.4、6.9、1.1、2.2、,
+指数=c(1,2,1,2,1,2),新指数=c(1L,1L,2L,2L,2L,3L,
+3L)),.Names=c(“单位”、“任何”、“索引”、“新”),row.Names=c(NA,
+-6L),class=c(“数据表”、“数据帧”),.internal.selfref=,sorted=c(“单位”,

错误:意外的“问题是,
dput
打印出外部指针地址(这是
data.table
在内部使用的内容,需要时将重新构造),而您不能真正使用它

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


您可以将FR添加到
data.table
中,但需要修改
data.table
中的基函数,类似于当前处理
rbind
的方式。

问题在于
dput
打印出外部指针地址(这是
data.table
在内部使用的东西,在需要时会重新构建),但您不能真正使用它

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


你可以在
数据.table
中添加一个FR,但这需要修改
数据.table
中的基函数,类似于
rbind
当前的处理方式。

我也发现这种行为相当烦人。因此我创建了自己的
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))
}

dput我也发现这种行为相当烦人。因此我创建了自己的
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))
}

dput如果您已经
dput
该文件,并且您不想在
dget
之前手动编辑,则可以使用以下方法

data.table.parse<-function (file = "", n = NULL, text = NULL, prompt = "?", keep.source = getOption("keep.source"), 
                            srcfile = NULL, encoding = "unknown") 
{
  keep.source <- isTRUE(keep.source)
  if (!is.null(text)) {
    if (length(text) == 0L) 
      return(expression())
    if (missing(srcfile)) {
      srcfile <- "<text>"
      if (keep.source) 
        srcfile <- srcfilecopy(srcfile, text)
    }
    file <- stdin()
  }
  else {
    if (is.character(file)) {
      if (file == "") {
        file <- stdin()
        if (missing(srcfile)) 
          srcfile <- "<stdin>"
      }
      else {
        filename <- file
        file <- file(filename, "r")
        if (missing(srcfile)) 
          srcfile <- filename
        if (keep.source) {
          text <- readLines(file, warn = FALSE)
          if (!length(text)) 
            text <- ""
          close(file)
          file <- stdin()
          srcfile <- srcfilecopy(filename, text, file.mtime(filename), 
                                 isFile = TRUE)
        }
        else {
          text <- readLines(file, warn = FALSE)
          if (!length(text)) {
            text <- ""
          } else {
            text <- gsub("(, .internal.selfref = <pointer: 0x[0-9A-Fa-f]+>)","",text,perl=TRUE)
          }
          on.exit(close(file))
        }
      }
    }
  }
  #  text <- gsub("(, .internal.selfref = <pointer: 0x[0-9A-F]+>)","",text)
  .Internal(parse(file, n, text, prompt, srcfile, encoding))
}
data.table.get <- function(file, keep.source = FALSE)
  eval(data.table.parse(file = file, keep.source = keep.source))
dtget <- data.table.get

data.table.parse如果您已经对文件进行了
dput
并且不想在
dget
之前手动编辑,则可以使用以下方法

data.table.parse<-function (file = "", n = NULL, text = NULL, prompt = "?", keep.source = getOption("keep.source"), 
                            srcfile = NULL, encoding = "unknown") 
{
  keep.source <- isTRUE(keep.source)
  if (!is.null(text)) {
    if (length(text) == 0L) 
      return(expression())
    if (missing(srcfile)) {
      srcfile <- "<text>"
      if (keep.source) 
        srcfile <- srcfilecopy(srcfile, text)
    }
    file <- stdin()
  }
  else {
    if (is.character(file)) {
      if (file == "") {
        file <- stdin()
        if (missing(srcfile)) 
          srcfile <- "<stdin>"
      }
      else {
        filename <- file
        file <- file(filename, "r")
        if (missing(srcfile)) 
          srcfile <- filename
        if (keep.source) {
          text <- readLines(file, warn = FALSE)
          if (!length(text)) 
            text <- ""
          close(file)
          file <- stdin()
          srcfile <- srcfilecopy(filename, text, file.mtime(filename), 
                                 isFile = TRUE)
        }
        else {
          text <- readLines(file, warn = FALSE)
          if (!length(text)) {
            text <- ""
          } else {
            text <- gsub("(, .internal.selfref = <pointer: 0x[0-9A-Fa-f]+>)","",text,perl=TRUE)
          }
          on.exit(close(file))
        }
      }
    }
  }
  #  text <- gsub("(, .internal.selfref = <pointer: 0x[0-9A-F]+>)","",text)
  .Internal(parse(file, n, text, prompt, srcfile, encoding))
}
data.table.get <- function(file, keep.source = FALSE)
  eval(data.table.parse(file = file, keep.source = keep.source))
dtget <- data.table.get

data.table.parses谢谢你的回答。你确定它不会影响dput对所有其他对象的输出吗?可以将此函数重命名为dputdt,以便仅用于data.table对象。为什么这么复杂?不是简单地
dput=function(x,…){if(is.data.table(x)){setattr(x,.internal.selfref',NULL)};base::dput(x,…)}
work?或者更好的方法是,将
is.data.table
替换为
inherits
,谢谢你的回答。你确定这不会影响dput对所有其他对象的输出吗?可以将此函数重命名为dputdt,以便仅用于data.table对象。为什么这么复杂?不简单地说
dput=function(x,…{如果(is.data.table(x)){setattr(x,'.internal.selfref',NULL)};base::dput(x,…)}
work?或者更好的方法是,将
is.data.table
替换为
inherits
我遇到了同样的问题,我所做的只是将因子列转换为字符,效果很好。我遇到了同样的问题,我所做的只是将因子列转换为字符,效果很好。