【发布时间】:2016-08-04 22:41:45
【问题描述】:
我有一个 data.table,其中包含几个具有相同值的二进制列,我想在一次操作中重新编码。我修改了一个最初为 data.frames 编写的函数,但不确定我是否真的以修改它的方式利用了 data.table 的速度:特别是我怀疑该函数可能仍在复制值。
如何确保函数通过引用替换值?
这是一个玩具数据集:
# Example data:
id <- c(1,2,3,4,5)
fruit <- c("apple", "orange", "banana", "strawbery", "rasberry")
mydate <- c("2015-09-01", "2015-09-02", "2015-11-15", "2016-02-24", "2016-03-08")
eaten <- c("y", "y", "n", "y", "u")
present <- c("n", "n", "y", "y", "y")
dt <- data.table(id, fruit, mydate, eaten, present)
dt[, mydate := as.Date(mydate, format = "%Y-%m-%d")]
dt[, sex := c("m", "f", "f", "m", "f")]
# Columns to update:
bincols <- c("eaten", "present")
在重新编码之前,数据如下所示:
> dt
id fruit mydate eaten present sex
1: 1 apple 2015-09-01 y n m
2: 2 orange 2015-09-02 y n f
3: 3 banana 2015-11-15 n y f
4: 4 strawbery 2016-02-24 y y m
5: 5 rasberry 2016-03-08 u y f
函数如下:
recode.multi <- function(datacols, oldval, newval) {
for (i in 1:length(datacols)) {
datacols[datacols == oldval[i]] = newval[i]
}
datacols
}
...应用于数据:
dt[, (bincols) := lapply(.SD, recode.multi, oldval = c("u", "n", "y"), newval = c(NA_real_, 0, 1)), .SDcols = bincols]
... 和输出,它会根据需要更新值,但不确定它是否在此过程中复制列?
> dt
id fruit mydate eaten present sex
1: 1 apple 2015-09-01 1 0 m
2: 2 orange 2015-09-02 1 0 f
3: 3 banana 2015-11-15 0 1 f
4: 4 strawbery 2016-02-24 1 1 m
5: 5 rasberry 2016-03-08 NA 1 f
我尝试将函数中的最后一个“=”更改为“:=”,但在重新检查“datacols”是否为 data.table 时出错。向函数添加子句以检查 is.data.table == TRUE 是否没有解决问题(返回相同的错误)。
任何关于最适合使用 data.table 方法来处理此功能的想法将不胜感激。
【问题讨论】:
-
不确定是否复制,但这是一段很好的代码。我不确定您在这里的意思:“我尝试将函数中的最后一个
=更改为:=。”您想更改哪个=? -
我试过了:
recode.multi <- function(datacols, oldval, newval) { for (i in 1:length(datacols)) { datacols[datacols == oldval[i]] := newval[i] } datacols }
标签: r function replace data.table multiple-columns