将函数应用于多个数据表
Apply function to multiple data tables
我有一些具有相同结构的数据表,我想对它们进行一些数据转换(创建新变量、分配缺失值等)
这是我试过的,没有成功。此代码 运行 没问题,但不会对数据表进行更改。有什么想法吗?
对于可重现的示例,运行 首先是这段代码
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[is.na(gear), gear := 0]
而不是 dataset$gear[is.na(dataset$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。
我有一些具有相同结构的数据表,我想对它们进行一些数据转换(创建新变量、分配缺失值等)
这是我试过的,没有成功。此代码 运行 没问题,但不会对数据表进行更改。有什么想法吗?
对于可重现的示例,运行 首先是这段代码
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[is.na(gear), gear := 0]
而不是 dataset$gear[is.na(dataset$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。