От 1_
NA — логическая константа длины 1, содержащая индикатор отсутствующего значения. NA можно привести к любому другому типу вектора, кроме исходного. Существуют также константы NA_integer_, NA_real_, NA_complex_ и NA_character_ других типов атомарных векторов, которые поддерживают пропущенные значения: все они являются зарезервированными словами в языке R.
Вам нужно будет указать правильный тип для работы вашей функции -
Вы можете заставить функцию соответствовать типу x
(обратите внимание, что нам нужно any
, чтобы это работало в ситуациях с более чем 1 строкой в подмножестве!
f <- function(x) {if any((x==9)) {return(as(NA, class(x)))} else { return(x)}}
Больше data.table*ish* подхода
Возможно, имеет больше смысла использовать data.table для установки/замены по ссылке с помощью set
(или :=
).
set(dtb, i = which(dtb[,a]==9), j = 'a', value=NA_integer_)
Или :=
в пределах [
, используя векторное сканирование для a==9
dtb[a == 9, a := NA_integer_]
Или :=
вместе с бинарным поиском
setkeyv(dtb, 'a')
dtb[J(9), a := NA_integer_]
Полезно отметить
Если вы используете подходы :=
или set
, вам не нужно указывать тип NA
Оба следующих будут работать
dtb <- data.table(a=1:10)
setkeyv(dtb,'a')
dtb[a==9,a := NA]
dtb <- data.table(a=1:10)
setkeyv(dtb,'a')
set(dtb, which(dtb[,a] == 9), 'a', NA)
Это дает очень полезное сообщение об ошибке, которое позволяет узнать причину и решение:
Ошибка в [.data.table
(DTc, J(9), :=
(a, NA)) : тип RHS («логический») должен соответствовать LHS («целое число»). Проверка и принуждение слишком сильно повлияют на производительность в самых быстрых случаях. Либо измените тип целевого столбца, либо задайте правую часть := самостоятельно (например, используя 1L вместо 1)
Что быстрее
с разумным большим набором данных, где a
заменяется на месте
Заменить на месте
library(data.table)
set.seed(1)
n <- 1e+07
DT <- data.table(a = sample(15, n, T))
setkeyv(DT, "a")
DTa <- copy(DT)
DTb <- copy(DT)
DTc <- copy(DT)
DTd <- copy(DT)
DTe <- copy(DT)
f <- function(x) {
if (any(x == 9)) {
return(as(NA, class(x)))
} else {
return(x)
}
}
system.time({DT[a == 9, `:=`(a, NA_integer_)]})
## user system elapsed
## 0.95 0.24 1.20
system.time({DTa[a == 9, `:=`(a, NA)]})
## user system elapsed
## 0.74 0.17 1.00
system.time({DTb[J(9), `:=`(a, NA_integer_)]})
## user system elapsed
## 0.02 0.00 0.02
system.time({set(DTc, which(DTc[, a] == 9), j = "a", value = NA)})
## user system elapsed
## 0.49 0.22 0.67
system.time({set(DTc, which(DTd[, a] == 9), j = "a", value = NA_integer_)})
## user system elapsed
## 0.54 0.06 0.58
system.time({DTe[, `:=`(a, f(a)), by = a]})
## user system elapsed
## 0.53 0.12 0.66
# The are all the same!
all(identical(DT, DTa), identical(DT, DTb), identical(DT, DTc), identical(DT,
DTd), identical(DT, DTe))
## [1] TRUE
Неудивительно, что подход бинарного поиска является самым быстрым.
person
mnel
schedule
13.09.2012