Dos formas de seleccionar variable (s) mediante programación:
with = FALSE:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE]
..prefijo 'dot dot' ( ):
DT[, ..colname]
Para obtener una descripción más detallada de la ..notación 'punto punto' ( ), consulte Nuevas funciones en 1.10.2 (actualmente no se describe en el texto de ayuda).
Para asignar a variable (s), coloque el LHS de :=entre paréntesis:
DT[, (colname) := 4:6]
Este último se conoce como plonk de columna , porque reemplaza el vector de columna completo por referencia. Si ihubiera un subconjunto , se subasignaría por referencia. El parens around (colname)es una taquigrafía introducida en la versión v1.9.4 en CRAN de octubre de 2014. Aquí está la noticia :
El uso de with = FALSEcon :=ahora está obsoleto en todos los casos, dado que :=durante algún tiempo se ha preferido envolver el LHS de entre paréntesis.
colVar = "col1"
DT[, (colVar) := 1]
DT[, c("col1", "col2") := 1]
DT[, 2:4 := 1]
DT[, c("col1","col2") := list(sum(a), mean(b))]
DT[, `:=`(...), by = ...]
Consulte también la sección Detalles en ?`:=`:
DT[i, (colnamevector) := value]
Y para responder más preguntas en el comentario, aquí hay una forma (como de costumbre, hay muchas formas):
DT[, colname := cumsum(get(colname)), with = FALSE]
o bien, puede que le resulte más fácil de leer, escribir y depurar sólo para evaluna paste, similar a la construcción de una sentencia de SQL dinámico para enviar a un servidor:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
eval(parse(text=expr))
Si lo hace mucho, puede definir una función auxiliar EVAL:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
Ahora que data.table1.8.2 optimiza automáticamente la jeficiencia, puede ser preferible utilizar el evalmétodo. El get()in jevita algunas optimizaciones, por ejemplo.
O lo hay set(). Una forma funcional de bajo costo, :=que estaría bien aquí. Ver ?set.
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
., o..evitar cualquier posible enmascaramiento siDTalguna vez contiene ese símbolo como nombre de columna en el futuro (y seguir la convención con la que los nombres de columna no comienzan.). Hay algunas solicitudes de funciones para que sea más sólido para problemas de alcance como ese, como agregar.()y..().fn$del paquete gsubfn para mejorar la legibilidad de la solución de EVAL:library(gsubfn); fn$EVAL( "DT[,$colname:=cumsum($colname)]" ).* Esta no es una respuesta en realidad, pero no tengo suficiente credibilidad en la calle para publicar comentarios: /
De todos modos, para cualquiera que esté buscando crear una nueva columna en una tabla de datos con un nombre almacenado en una variable, tengo lo siguiente para trabajar. No tengo ni idea de su rendimiento. ¿Alguna sugerencia de mejora? ¿Es seguro asumir que una nueva columna sin nombre siempre recibirá el nombre V1?
colname <- as.name("users") # Google Analytics query is run with chosen metric and resulting data is assigned to DT DT2 <- DT[, sum(eval(colname, .SD)), by = country] setnames(DT2, "V1", as.character(colname))Observe que puedo hacer referencia a él bien en la suma () pero parece que no puedo hacer que se asigne en el mismo paso. Por cierto, la razón por la que necesito hacer esto es que colname se basará en la entrada del usuario en una aplicación Shiny.
fuente
V1es el nuevo nombre. Por ejemplo, si lee csv confready hay una columna sin nombre, tendráV1nombre (yread.csvdaráX). Entonces es posible que su mesa ya tenga unV1. Tal vez solo obtenga el nombre pornames(DT)[length(names(DT))]Para múltiples columnas y una función aplicada a valores de columna.
Al actualizar los valores de una función, el RHS debe ser un objeto de lista, por lo que usar un bucle en
.SDconlapplyhará el truco.El siguiente ejemplo convierte columnas enteras en columnas numéricas
a1 <- data.table(a=1:5, b=6:10, c1=letters[1:5]) sapply(a1, class) # show classes of columns # a b c1 # "integer" "integer" "character" # column name character vector nm <- c("a", "b") # Convert columns a and b to numeric type a1[, j = (nm) := lapply(.SD, as.numeric ), .SDcols = nm ] sapply(a1, class) # a b c1 # "numeric" "numeric" "character"fuente
Recupere múltiples columnas de data.table a través de variable o función:
library(data.table) x <- data.table(this=1:2,that=1:2,whatever=1:2) # === explicit call x[, .(that, whatever)] x[, c('that', 'whatever')] # === indirect via variable # ... direct assignment mycols <- c('that','whatever') # ... same as result of a function call mycols <- grep('a', colnames(x), value=TRUE) x[, ..mycols] x[, .SD, .SDcols=mycols] # === direct 1-liner usage x[, .SD, .SDcols=c('that','whatever')] x[, .SD, .SDcols=grep('a', colnames(x), value=TRUE)]que todos ceden
that whatever 1: 1 1 2: 2 2Encuentro el
.SDcolscamino más elegante.fuente
Podrías intentar esto
colname <- as.name ("COL_NAME")
DT2 <- DT [, lista (COL_SUM = sum (eval (colname, .SD))), por = c (grupo)]
fuente