data.table 在函数中使用时的奇怪行为

data.table weird behaviour when used in a function

我有一个data.frame如下。

data <- structure(list(V1 = structure(1:3, .Label = c("S01", "S02", "S03"), class = "factor"), V2 = structure(c(1L, 3L, 2L), .Label = c("Alan", "Bruce", "Jay"), class = "factor"), V3 = structure(c(3L, 1L, 2L), .Label = c("Barry", "Dick", "Hal"), class = "factor"), V4 = structure(c(1L, 3L, 2L), .Label = c("Guy", "Jean-Paul", "Wally"), class = "factor"), V5 = structure(c(3L, 1L, 2L), .Label = c("Bart", "Damien", "John"), class = "factor")), .Names = c("V1", "V2", "V3", "V4", "V5"), class = "data.frame", row.names = c(NA, -3L))

这不是 data.table

is.data.table(data)
[1] FALSE

例如,我有一个函数 foo,它利用 data.tabledata.frame 中进行如下操作。

foo <- function(df) {
  if(!is.data.frame(df)) stop('"df" is not a data.frame')
  setDT(df)
  setkey(df, V1)
  df[, "NEW" := paste0(V3, V4), with = FALSE]
  setDF(df)
  return(df)
}

然而,当我 运行 带有 data.frame data 的函数(不是 data.table)时,输出 outdata.frame(因为 setDF(df))。

out <- foo(data)
is.data.table(out)
[1] FALSE

但是现在原来的data.framedata变成了data.table.

is.data.table(data)
[1] TRUE

我理解这是因为 data.table 是通过引用工作的。但是在函数中使用时如何处理这个问题。我不想无意中更改环境中的任何 data.frame。每当在函数中使用 data.table 时,我是否应该始终使用 copy<- 而不是 setDT 强制复制,还是有其他方法?

关于

is there another way?

而不是函数内部的 setDT(),您可以使用 as.data.table()

foo <- function(df) {
    if(!is.data.frame(df)) stop('"df" is not a data.frame')
    df <- as.data.table(df)
    setkey(df, V1)
    df[, NEW := paste0(V3, V4)]
    setDF(df)
    return(df)
}

foo(data)
#    V1    V2    V3        V4     V5           NEW
# 1 S01  Alan   Hal       Guy   John        HalGuy
# 2 S02   Jay Barry     Wally   Bart    BarryWally
# 3 S03 Bruce  Dick Jean-Paul Damien DickJean-Paul

is.data.table(data)
# [1] FALSE

有关将输入数据 frame 转换为数据 table 但不更改原始数据的一些函数示例数据框,我绝对建议查看包 splitstackshape.

中函数的源代码