我有一些具有相同结构的数据表,我想对它们进行一些数据转换(创建新变量,分配缺失值等)
这是我尝试过的,没有成功。此代码运行正常,但不会更改数据表。有什么想法吗?
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)
正如您所看到的,该函数运行fin,但它没有修改数据表。你对此有何看法?
答案 0 :(得分:6)
您的主要问题是您使用的语法不正确。这种方式dataset$gear[is.na(dataset$gear)] <- 0
将dataset[is.na(gear), gear := 0]
修改:=
的词法范围 以外的原始数据集,而不是lapply
<-
。 {1}}仅在某个函数的词法范围内运行)。因此将您的功能修改为
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。