tablas - seleccionar filas en r
Seleccione NA en una tabla de datos en R (2)
¿Cómo selecciono todas las filas que tienen un valor faltante en la clave principal en una tabla de datos?
DT = data.table(x=rep(c("a","b",NA),each=3), y=c(1,3,6), v=1:9)
setkey(DT,x)
Seleccionar un valor en particular es fácil
DT["a",]
La selección de los valores faltantes parece requerir una búsqueda vectorial. No se puede usar la búsqueda binaria. ¿Estoy en lo correcto?
DT[NA,]# does not work
DT[is.na(x),] #does work
Esto ahora se implementa en v1.8.11. De NEWS :
o La búsqueda binaria ahora puede subconjuntar
NA
/NaN
y también realizarjoins
ymerges
al hacer corresponderNA
s /NaN
s.
Aunque deberás proporcionar la NA
correcta ( NA_real_
, NA_character_
etc.) explícitamente en este momento.
En los datos de OP:
DT[J(NA_character_)] # or for characters simply DT[NA_character_]
# x y v
# 1: NA 1 7
# 2: NA 3 8
# 3: NA 6 9
Además, este es el mismo punto de referencia de la publicación de @ JoshOBrien, con esta búsqueda binaria para NA agregada:
library(data.table)
library(rbenchmark)
DT = data.table(x=rep(c("a","b",NA),each=3e6), y=c(1,3,6), v=1:9)
setkey(DT,x)
benchmark(DT["a",],
DT[is.na(x),],
DT[NA_character_],
replications=20)
test replications elapsed relative user.self sys.self
1 DT["a", ] 20 4.763 1.238 4.000 0.567
2 DT[is.na(x), ] 20 5.399 1.403 4.537 0.794
3 DT[NA] 20 3.847 1.000 3.215 0.600 # <~~~
Afortunadamente, DT[is.na(x),]
es casi tan rápido como (por ejemplo) DT["a",]
, por lo que en la práctica, esto puede no importar mucho:
library(data.table)
library(rbenchmark)
DT = data.table(x=rep(c("a","b",NA),each=3e6), y=c(1,3,6), v=1:9)
setkey(DT,x)
benchmark(DT["a",],
DT[is.na(x),],
replications=20)
# test replications elapsed relative user.self sys.self user.child
# 1 DT["a", ] 20 9.18 1.000 7.31 1.83 NA
# 2 DT[is.na(x), ] 20 10.55 1.149 8.69 1.85 NA
===
Adición de Matthew (no cabe en el comentario):
Sin embargo, los datos anteriores tienen 3 grupos muy grandes. Entonces, la ventaja de velocidad de la búsqueda binaria está dominada aquí por el tiempo para crear el subconjunto grande (se copia 1/3 de los datos).
benchmark(DT["a",], # repeat select of large subset on my netbook
DT[is.na(x),],
replications=3)
test replications elapsed relative user.self sys.self
DT["a", ] 3 2.406 1.000 2.357 0.044
DT[is.na(x), ] 3 3.876 1.611 3.812 0.056
benchmark(DT["a",which=TRUE], # isolate search time
DT[is.na(x),which=TRUE],
replications=3)
test replications elapsed relative user.self sys.self
DT["a", which = TRUE] 3 0.492 1.000 0.492 0.000
DT[is.na(x), which = TRUE] 3 2.941 5.978 2.932 0.004
A medida que disminuye el tamaño del subconjunto devuelto (por ejemplo, agregando más grupos), la diferencia se vuelve evidente. Los escaneos vectoriales en una sola columna no son tan malos, pero en 2 o más columnas se degrada rápidamente.
Quizás las NA deberían ser compatibles. Sin embargo, parece recordar un gotcha con eso. Aquí hay un historial vinculado con FR # 1043 ¿Permitir o no permitir NA en las claves? . NA_integer_
menciona que NA_integer_
es internamente un entero negativo. Eso activa la ordenación de radix / counting (iirc), lo que hace que setkey
más lento. Pero está en la lista para volver a visitar.