Dwa sposoby programowego wybierania zmiennych:
with = FALSE
:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE]
..
Przedrostek „kropka kropka” ( ):
DT[, ..colname]
Więcej informacji na temat notacji „kropka kropka” ( ..
) można znaleźć w sekcji Nowe funkcje w wersji 1.10.2 (obecnie nie jest ona opisana w tekście pomocy).
Aby przypisać do zmiennych, zawiń LHS lub :=
w nawiasy:
DT[, (colname) := 4:6]
Ten ostatni jest znany jako plonk kolumny , ponieważ zastępujesz cały wektor kolumny przez odniesienie. Jeśli podzbiór i
był obecny, będzie to przypisywanie podrzędne przez odniesienie. Parens (colname)
to skrót wprowadzony w wersji v1.9.4 w CRAN w październiku 2014 r. Oto aktualności :
Używanie with = FALSE
with :=
jest teraz przestarzałe we wszystkich przypadkach, biorąc pod uwagę, że zawijanie LHS :=
z nawiasami jest preferowane od jakiegoś czasu.
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 = ...]
Zobacz także sekcję Szczegóły w ?`:=`
:
DT[i, (colnamevector) := value]
Aby odpowiedzieć na dalsze pytanie w komentarzu, oto jeden sposób (jak zwykle jest wiele sposobów):
DT[, colname := cumsum(get(colname)), with = FALSE]
lub, może być łatwiejsze czytanie, pisanie i debugowanie tylko do eval
a paste
, podobnie do konstruowania dynamicznej instrukcji SQL do wysłania na serwer:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
eval(parse(text=expr))
Jeśli często to robisz, możesz zdefiniować funkcję pomocniczą EVAL
:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
Teraz, gdy data.table
1.8.2 automatycznie optymalizuje się j
pod kątem wydajności, preferowane może być użycie tej eval
metody. get()
W j
zabezpiecza pewne optymalizacje, na przykład.
Albo jest set()
. Niska, funkcjonalna forma :=
, która byłaby tutaj w porządku. Zobacz ?set
.
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
.
lub w..
celu uniknięcia potencjalnego maskowania, jeśliDT
w przyszłości będzie zawierać ten symbol jako nazwę kolumny (i trzymaj się konwencji, od której nazwy kolumn nie zaczynają się.
). Istnieją pewne żądania funkcji, aby uczynić go bardziej odpornym na problemy z zakresem, takie jak dodawanie.()
i..()
.fn$
pakiecie gsubfn do poprawy czytelności rozwiązania EVAL:library(gsubfn); fn$EVAL( "DT[,$colname:=cumsum($colname)]" )
.* To nie jest prawdziwa odpowiedź, ale nie mam wystarczających danych na temat ulicy, aby dodawać komentarze: /
W każdym razie, dla każdego, kto chciałby faktycznie utworzyć nową kolumnę w tabeli danych z nazwą przechowywaną w zmiennej, mam do pracy następujące rzeczy. Nie mam pojęcia, jak to działa. Jakieś sugestie dotyczące ulepszeń? Czy można bezpiecznie założyć, że bezimienna nowa kolumna zawsze otrzyma nazwę 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))
Zauważ, że mogę odwołać się do tego w sumie (), ale nie mogę go przypisać w tym samym kroku. BTW, powodem, dla którego muszę to zrobić, jest to, że nazwa kolumny będzie oparta na danych wprowadzonych przez użytkownika w aplikacji Shiny.
źródło
V1
jest to nowa nazwa. Na przykład, jeśli czytasz csv zfread
i istnieje nienazwana kolumna, będzie miałaV1
nazwę (iread.csv
daX
). Więc możliwe, że Twój stół ma już plikV1
. Może po prostu zdobądź nazwę przeznames(DT)[length(names(DT))]
Dla wielu kolumn i funkcji zastosowanej do wartości kolumn.
Podczas aktualizowania wartości z funkcji, RHS musi być obiektem listy, więc użycie pętli na
.SD
withlapply
załatwi sprawę.Poniższy przykład konwertuje kolumny liczb całkowitych na kolumny liczbowe
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"
źródło
Pobierz wiele kolumn z data.table za pomocą zmiennej lub funkcji:
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)]
które wszystkie dają
that whatever 1: 1 1 2: 2 2
Uważam, że
.SDcols
droga jest najbardziej elegancka.źródło
Możesz tego spróbować
colname <- as.name („COL_NAME”)
DT2 <- DT [, list (COL_SUM = sum (eval (nazwa kolumny, .SD))), by = c (grupa)]
źródło