De ?NA
NA es una constante lógica de longitud 1, que contiene un indicador de valor que falta. NA puede ser coaccionado a cualquier otro tipo de vector, excepto en bruto. También hay constantes NA_integer_, NA_real_, NA_complex_ y NA_character_ de los otros tipos de vectores atómicos que admiten valores faltantes: todas estas son palabras reservadas en el lenguaje R.
Tendrá que especificar el tipo correcto para su función trabaje -
Puede coaccionar dentro de la función para que coincida con el tipo de x
(nótese que necesitamos any
para que esto funcione para situaciones con más de 1 fila en un subconjunto!
f <- function(x) {if any((x==9)) {return(as(NA, class(x)))} else { return(x)}}
más data.table * * ish enfoque
podría tener sentido más data.table de usar set
(o :=
) para establecer/reemplazar por referencia.
set(dtb, i = which(dtb[,a]==9), j = 'a', value=NA_integer_)
O :=
dentro [
usando una exploración vector para a==9
dtb[a == 9, a := NA_integer_]
O :=
junto con una búsqueda binaria
setkeyv(dtb, 'a')
dtb[J(9), a := NA_integer_]
útil señalar
Si utiliza el :=
o set
enfoques, que no parece que tenga que especificar el tipo NA
Tanto el siguiente trabajo
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)
Esto da un mensaje de error muy útil que le permite saber la razón y la solución:
Error en [.data.table
(DTC, J (9), :=
(a, NA)): Tipo de RHS ('lógico') debe coincidir LHS ('entero'). Controlar y coaccionar afectaría demasiado el rendimiento para los casos más rápidos. Cambie el tipo de la columna de destino o fuerce la RHS de: = usted mismo (p.mediante el uso de 1L en vez de 1)
Lo que es más rápida
con una gran data.set razonable donde a
se sustituye in situ
Reemplazar en situ
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
Como era de esperar, el enfoque de búsqueda binaria es el más rápido
posible duplicado de [¿Por qué el viaje hasta la mediana data.table (entero frente doble)?] (Http: // stackoverflow.com/questions/12125364/why-does-median-trip-up-data-table-integer-versus-double) –
También tuve un problema relacionado una vez: [Dividir una data.table con el by-operator: funciones que devuelven valores numéricos y/o NA fallan] (http://stackoverflow.com/questions/7960798/splitting-a-data-table-with-the-by-operator-functions-that-return-numeric-value) –
@Alex Cuando la pregunta es acerca de un mensaje de error, intente buscar SO para el mensaje de error Por ejemplo [esta búsqueda] (http://stackoverflow.com/search?q=%5Bdata.table%5D+%22columns+of+j+don%27t+evanced+to+consistent+types+for+each+group% 22 & submit = search) devuelve los 2 enlaces anteriores y un 3º también. –