我有一些结构相同的数据表,我想对它们进行一些数据转换(创建新变量,分配缺失值等)

这是我试过的,没有成功。此代码运行正常,但不会更改数据表。有任何想法吗?

对于可重现的示例,请先运行此代码片段

data("mtcars")              # load data
setDT(mtcars)               # convert to data table
mtcars[gear==5, gear :=NA]  # create NA values for the purpose of my application
mtcars2 <- mtcars           # create second DT

我的代码
# Create function
  computeWidth <- function(dataset){
                                    dataset$gear[is.na(dataset$gear)] <- 0 # Convert NA to 0
                                    dataset[ ,width := hp + gear]          # create new variable
                                    }

# Apply function
  lapply(list(mtcars, mtcars2), computeWidth)

如您所见,该函数可以正常工作,但它没有修改数据表。对此有何想法?

最佳答案

您的主要问题是您使用的语法不正确。您应该使用 dataset$gear[is.na(dataset$gear)] <- 0 而不是 dataset[is.na(gear), gear := 0] ,这样 := 将修改 lapply 词法范围之外的原始数据集( <- 仅在某个函数的词法范围内运行)。因此将您的功能修改为

computeWidth <- function(dataset){
  dataset[is.na(gear), gear := 0] # Convert NA to 0
  dataset[ ,width := hp + gear]   # create new variable
}

然后运行
lapply(list(mtcars, mtcars2), computeWidth)

将修改原始数据集。

作为旁注,如果您想将其推广到许多 data.table 对象,您可以查看 tables 函数并尝试如下操作
lapply(mget(tables(silent = TRUE)$NAME), computeWidth)

尽管最好首先将多个对象保存在一个列表中,而不是用许多对象填充全局环境。

一个非常重要的注意事项(由@Frank 建议),您应该意识到在未修改的 <- 上使用 data.table 时,您实际上并不是在创建新对象
mtcars2 <- mtcars
tracemem(mtcars)
## [1] "<00000000129264F8>"
tracemem(mtcars2)
## [1] "<00000000129264F8>"

因此,仅通过修改 mtcars 您也将修改 mtcars2 。相反,正确的做法是使用 copy 作为
mtcars2 <- copy(mtcars)
tracemem(mtcars)
## [1] "<00000000129264F8>"
tracemem(mtcars2)
## [1] "<000000001315F6B8>"

有关更多详细信息,请参阅 here

关于r - 将函数应用于多个数据表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32841817/

10-12 13:59
查看更多