.SDparece útil pero realmente no sé qué estoy haciendo con él. Que significa? ¿Por qué hay un período anterior (punto final)? ¿Qué sucede cuando lo uso?
Leí:
.SDes un que data.tablecontiene el subconjunto de xdatos de cada grupo, excluyendo las columnas del grupo. Se puede usar al agrupar por i, al agrupar por by, con clave byy _ad hoc_by
¿Eso significa que la hija data.tablese guarda en la memoria para la próxima operación?
r
data.table
Farrel
fuente
fuente

?data.tablefue mejorado en v1.7.10, gracias a esta pregunta. Ahora explica el nombre.SDsegún la respuesta aceptada.Respuestas:
.SDsignifica algo como "Subset ofData.table". La inicial no tiene importancia".", excepto que hace que sea aún más improbable que haya un choque con un nombre de columna definido por el usuario.Si este es su data.table:
Hacer esto puede ayudarlo a ver qué
.SDes:Básicamente, la
by=ydeclaración divide la tabla de datos original en estos dos sub-data.tablesy opera en ellos a su vez.
Mientras está operando en cualquiera de los dos, le permite referirse al subtítulo actual
data.tableutilizando el apodo / identificador / símbolo.SD. Eso es muy útil, ya que puede acceder y operar en las columnas como si estuviera sentado en la línea de comando trabajando con una sola tabla de datos llamada.SD... excepto que aquí,data.tablellevará a cabo esas operaciones en cada uno de los subdefinidosdata.tablepor combinaciones de la clave, "pegarlas" de nuevo juntas y devolver los resultados en un solodata.table!fuente
.SDesDT[,print(.SD),by=y].DT[,print(.SD[,y]),by=y], indica que tengo acceso al valor dey, aunque no sea parte de.SD. ¿De dónde es el valor deyser explorado? ¿Está disponible b / c es el valor actual deby?.SD[,y]es undata.tablesubconjunto regular, yayque no se ve una columna.SDen el entorno que lo llamó, que en este caso es eljentorno (de laDTconsulta) dondebyestán disponibles las variables. Si no se encuentra allí, se ve en el padre, y en su padre, etc., de la forma habitual de R. (Bueno, también a través del alcance heredado de unión, que no se usa en estos ejemplos porque no hayis).by=list(x,y,z)significaríax,yyzestán disponibles paraj. Para acceso genérico también están envueltos.BY. La pregunta frecuente 2.10 tiene algo de historia, pero podría agregarse algo de claridad?data.table. Genial, la ayuda documental sería muy bienvenida. Aún mejor si desea unirse al proyecto y cambiar directamente.Editar:
Dado lo bien recibida que fue esta respuesta, la he convertido en una viñeta de paquete ahora disponible aquí
Dada la frecuencia con la que esto ocurre, creo que esto justifica un poco más de exposición, más allá de la útil respuesta dada por Josh O'Brien arriba.
Además del S ubset del acrónimo D ata generalmente citado / creado por Josh, creo que también es útil considerar que la "S" significa "Selfsame" o "Self-reference" -
.SDes en su forma más básica un referencia reflexiva adata.tablesí mismo: como veremos en los ejemplos a continuación, esto es particularmente útil para encadenar "consultas" (extracciones / subconjuntos / etc. usando[). En particular, esto también significa que.SDes en sí undata.table(con la advertencia de que no permite la asignación con:=).El uso más simple de
.SDes para subconjuntos de columnas (es decir, cuándo.SDcolsse especifica); Creo que esta versión es mucho más sencilla de entender, por lo que cubriremos eso primero a continuación. La interpretación de.SDen su segundo uso, los escenarios de agrupación (es decir, cuándoby =okeyby =se especifica), es ligeramente diferente, conceptualmente (aunque en el fondo es lo mismo, ya que, después de todo, una operación no agrupada es un caso extremo de agrupación con solo un grupo).Aquí hay algunos ejemplos ilustrativos y algunos otros ejemplos de usos que yo mismo implemento a menudo:
Cargando datos de Lahman
Para darle a esto una sensación más real, en lugar de inventar datos, carguemos algunos conjuntos de datos sobre el béisbol de
Lahman:Desnudo
.SDPara ilustrar lo que quiero decir sobre la naturaleza reflexiva de
.SD, considere su uso más banal:Es decir, acabamos de regresar
Pitching, es decir, esta era una forma excesivamente detallada de escribirPitchingoPitching[]:En términos de subconjunto,
.SDsigue siendo un subconjunto de los datos, es solo trivial (el conjunto en sí).Subconjunto de columnas:
.SDcolsLa primera forma de afectar lo que
.SDes es limitar las columnas contenidas en el.SDuso del.SDcolsargumento para[:Esto es solo para ilustración y fue bastante aburrido. Pero incluso este simple uso se presta a una amplia variedad de operaciones de manipulación de datos altamente beneficiosas / ubicuas:
Conversión de tipo de columna
La conversión del tipo de columna es una realidad para la mezcla de datos: a partir de este escrito,
fwriteno se puede leer automáticamenteDateoPOSIXctcolumnas , y las conversiones de ida y vuelta entrecharacter/factor/numericson comunes. Podemos usar.SDy.SDcolsconvertir por lotes grupos de tales columnas.Notamos que las siguientes columnas se almacenan como
characteren elTeamsconjunto de datos:Si está confundido por el uso de
sapplyaquí, tenga en cuenta que es lo mismo que para la base Rdata.frames:La clave para comprender esta sintaxis es recordar que a
data.table(así como adata.frame) se puede considerar como un lugarlistdonde cada elemento es una columna; por lo tanto,sapply/ selapplyaplicaFUNa cada columna y devuelve el resultado comosapply/lapplynormalmente lo haría (aquí,FUN == is.characterdevuelve unlogicalde longitud 1, entoncessapplydevuelve un vector).La sintaxis para convertir estas columnas
factores muy similar: simplemente agregue el:=operador de asignaciónTenga en cuenta que debemos incluir
fktparéntesis()para forzar a R a interpretar esto como nombres de columna, en lugar de intentar asignar el nombrefktal RHS.La flexibilidad de
.SDcols(y:=) para aceptar uncharactervector o unintegervector de posiciones de columna también puede ser útil para la conversión basada en patrones de nombres de columna *. Podríamos convertir todas lasfactorcolumnas acharacter:Y luego convierta todas las columnas que contienen de
teamnuevo afactor:** El uso explícito de números de columna (como
DT[ , (1) := rnorm(.N)]) es una mala práctica y puede conducir a un código silenciosamente dañado con el tiempo si cambian las posiciones de las columnas. Incluso el uso implícito de números puede ser peligroso si no mantenemos un control inteligente / estricto sobre el orden de cuándo creamos el índice numerado y cuándo lo usamos.Control de RHS de un modelo
La especificación del modelo variable es una característica central del análisis estadístico robusto. Tratemos de predecir la ERA de un lanzador (Promedio de carreras ganadas, una medida de rendimiento) usando el pequeño conjunto de covariables disponibles en la
Pitchingtabla. ¿Cómo funciona la relación (lineal) entreW(victorias) yERAdependiendo de qué otras covariables se incluyen en la especificación?Aquí hay un breve guión que aprovecha el poder del
.SDcual explora esta pregunta:El coeficiente siempre tiene el signo esperado (los mejores lanzadores tienden a tener más victorias y menos carreras permitidas), pero la magnitud puede variar sustancialmente dependiendo de qué más controlemos.
Uniones condicionales
data.tableLa sintaxis es hermosa por su simplicidad y robustez. La sintaxisx[i]maneja de manera flexible dos enfoques comunes de subconjunto: cuandoies unlogicalvector,x[i]devolverá esas filasxcorrespondientes a dondeiestáTRUE; cuandoies otrodata.table,joinse realiza a (en forma simple, usando lakeys dexyi, de lo contrario, cuandoon =se especifica, usando coincidencias de esas columnas).Esto es genial en general, pero se queda corto cuando deseamos realizar una unión condicional , en donde la naturaleza exacta de la relación entre tablas depende de algunas características de las filas en una o más columnas.
Este ejemplo es un poco artificial, pero ilustra la idea; ver aquí ( 1 , 2 ) para más.
El objetivo es agregar una columna
team_performancea laPitchingtabla que registre el desempeño del equipo (rango) del mejor lanzador en cada equipo (medido por la efectividad más baja, entre los lanzadores con al menos 6 juegos registrados).Tenga en cuenta que la
x[y]sintaxis devuelvenrow(y)valores, razón por la cual.SDestá a la derecha enTeams[.SD](ya que el RHS de:=en este caso requierenrow(Pitching[rank_in_team == 1])valores..SDOperaciones agrupadasA menudo, nos gustaría realizar alguna operación en nuestros datos a nivel de grupo . Cuando especificamos
by =(okeyby =), el modelo mental de lo que sucede cuando losdata.tableprocesosjes pensardata.tableque se divide en muchos subcomponentesdata.table, cada uno de los cuales corresponde a un solo valor de suby(s) variable (s):En este caso,
.SDes de naturaleza múltiple: se refiere a cada uno de estos subdata.table, uno a la vez (un poco más exactamente, el alcance de.SDun sub-data.table). Esto nos permite expresar de manera concisa una operación que nos gustaría realizar en cada sub-data.tableantes de que el resultado reensamblado nos sea devuelto.Esto es útil en una variedad de configuraciones, las más comunes de las cuales se presentan aquí:
Subconjunto de grupo
Obtengamos la temporada de datos más reciente para cada equipo en los datos de Lahman. Esto se puede hacer simplemente con:
Recuerde que en
.SDsí mismo es undata.table, y que se.Nrefiere al número total de filas en un grupo (es igual anrow(.SD)dentro de cada grupo), por lo que.SD[.N]devuelve la totalidad de.SDla fila final asociada a cada unoteamID.Otra versión común de esto es usar
.SD[1L]en su lugar para obtener la primera observación para cada grupo.Grupo Optima
Supongamos que queremos devolver el mejor año para cada equipo, medido por su número total de carreras anotadas (
Rpor supuesto, podríamos ajustar esto fácilmente para referirnos a otras métricas). En lugar de tomar un elemento fijo de cada sub-data.table, ahora definimos el índice deseado dinámicamente de la siguiente manera:Tenga en cuenta que, por supuesto, este enfoque se puede combinar
.SDcolspara devolver solo partes dedata.tablecada uno.SD(con la advertencia que.SDcolsdebe corregirse en los distintos subconjuntos)NB :
.SD[1L]actualmente está optimizado porGForce( vea también ),data.tablecomponentes internos que aceleran masivamente las operaciones agrupadas más comunes comosumomean- vea?GForcepara más detalles y esté atento / soporte de voz para solicitudes de mejoras de características para actualizaciones en este frente: 1 , 2 , 3 , 4 , 5 , 6Regresión Agrupada
Volviendo a la consulta anterior sobre la relación entre
ERAyW, supongamos que esperamos que esta relación difiera según el equipo (es decir, hay una pendiente diferente para cada equipo). Podemos volver a ejecutar fácilmente esta regresión para explorar la heterogeneidad en esta relación de la siguiente manera (observando que los errores estándar de este enfoque son generalmente incorrectos, la especificaciónERA ~ W*teamIDserá mejor, este enfoque es más fácil de leer y los coeficientes están bien) :Si bien existe una buena cantidad de heterogeneidad, existe una concentración clara alrededor del valor general observado
¡Esperemos que esto haya aclarado el poder de
.SDfacilitar un código hermoso y eficientedata.table!fuente
Hice un video sobre esto después de hablar con Matt Dowle sobre .SD, puedes verlo en YouTube: https://www.youtube.com/watch?v=DwEzQuYfMsI
fuente