Duas maneiras de selecionar variável (s) de forma programática :
with = FALSE
:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE]
'ponto ponto' ( ..
) prefixo:
DT[, ..colname]
Para obter uma descrição mais detalhada da ..
notação 'ponto ponto' ( ), consulte Novos recursos em 1.10.2 (atualmente não está descrito no texto de ajuda).
Para atribuir a variável (s), coloque o LHS de :=
entre parênteses:
DT[, (colname) := 4:6]
O último é conhecido como plonk de coluna , porque você substitui todo o vetor de coluna por referência. Se um subconjunto i
estivesse presente, ele seria subatribuído por referência. Os parênteses ao redor (colname)
são uma abreviação introduzida na versão v1.9.4 no CRAN de outubro de 2014. Aqui está o item de notícias :
Usar with = FALSE
com :=
agora está obsoleto em todos os casos, uma vez que :=
há algum tempo é preferível envolver o LHS de entre parênteses.
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 também a seção Detalhes em ?`:=`
:
DT[i, (colnamevector) := value]
E para responder a outras perguntas no comentário, aqui está uma maneira (como de costume, há muitas maneiras):
DT[, colname := cumsum(get(colname)), with = FALSE]
ou, você pode achar mais fácil ler, escrever e depurar apenas em eval
um paste
, semelhante a construir uma instrução SQL dinâmica para enviar a um servidor:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
eval(parse(text=expr))
Se você faz muito isso, pode definir uma função auxiliar EVAL
:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
Agora que data.table
1.8.2 otimiza automaticamente j
para eficiência, pode ser preferível usar o eval
método. O get()
in j
impede algumas otimizações, por exemplo.
Ou, existe set()
. Uma baixa sobrecarga, forma funcional de :=
, o que seria ótimo aqui. Veja ?set
.
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
.
, ou..
evitar qualquer mascaramento potencial, seDT
alguma vez contiver esse símbolo como um nome de coluna no futuro (e seguir a convenção de que nomes de coluna não começam com.
). Existem algumas solicitações de recursos para torná-lo mais robusto para questões de escopo como essa, como adicionar.()
e..()
.fn$
do pacote gsubfn para melhorar a legibilidade da solução EVAL:library(gsubfn); fn$EVAL( "DT[,$colname:=cumsum($colname)]" )
.* Esta não é uma resposta, mas não tenho credibilidade suficiente para postar comentários: /
De qualquer forma, para qualquer um que esteja procurando realmente criar uma nova coluna em uma tabela de dados com um nome armazenado em uma variável, tenho o seguinte para funcionar. Não tenho ideia de seu desempenho. Alguma sugestão de melhoria? É seguro presumir que uma nova coluna sem nome sempre receberá o nome 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 posso referenciá-lo bem no sum (), mas não consigo fazer com que seja atribuído na mesma etapa. BTW, o motivo pelo qual preciso fazer isso é colname será baseado na entrada do usuário em um aplicativo Shiny.
fonte
V1
é o novo nome. Por exemplo, se você ler csv comfread
e houver uma coluna sem nome, ela teráV1
nome (eread.csv
forneceráX
). Portanto, é possível que sua mesa já tenha umV1
. Talvez apenas receba o nome pornames(DT)[length(names(DT))]
Recupere várias colunas de data.table por meio de variável ou função:
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 rendem
that whatever 1: 1 1 2: 2 2
Acho a
.SDcols
forma mais elegante.fonte
Para várias colunas e uma função aplicada aos valores da coluna.
Ao atualizar os valores de uma função, o RHS deve ser um objeto de lista, portanto, usando um loop em
.SD
comlapply
fará o truque.O exemplo abaixo converte colunas inteiras em colunas 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"
fonte
Você poderia tentar isso
colname <- as.name ("COL_NAME")
DT2 <- DT [, lista (COL_SUM = sum (eval (colname, .SD))), por = c (grupo)]
fonte