Wybierz kolumny danych.tabela oparta na regex
Jak mogę wybrać kolumny danych.tabela oparta na regex? Rozważmy prosty przykład w następujący sposób:
library(data.table)
mydt <- data.table(foo=c(1,2), bar=c(2,3), baz=c(3,4))
Czy istnieje sposób na użycie kolumn bar
i baz
z datatable na podstawie regex? Wiem, że poniższe rozwiązanie działa, ale jeśli tabela jest znacznie większa i chciałbym wybrać więcej zmiennych, może to łatwo się uciążliwe.
mydt[, .(bar, baz)]
Chciałbym mieć coś w rodzaju matches()
w dplyr::select()
, ale tylko przez odniesienie.
6 answers
Możesz również spróbować użyć %like%
z data.table
pakietu, który jest "funkcją wygodną do wywoływania regexpr". Jednak sprawia, że kod jest bardziej czytelny;)
W tym przypadku, odpowiadając na twoje pytanie:
mydt[, .SD, .SDcols = names(mydt) %like% "bar|baz"]
Ponieważ %like%
zwraca wektor logiczny, whe może użyć poniższego, aby uzyskać każdą kolumnę z wyjątkiem tych, które zawierają "foo":
mydt[, .SD, .SDcols = ! names(mydt) %like% "foo"]
Gdzie !
neguje wektor logiczny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 10:54:55
Odpowiedź Davida zadziała. Ale jeśli Twoje Wyrażenie regularne jest długie i wolisz, aby zostało zrobione jako pierwsze, spróbuj:
cols <- grep("<regex pattern>", names(mydt), value=T)
mydt[, cols, with=FALSE]
To zależy tylko od Twoich preferencji i potrzeb. Możesz również przypisać tabelę podzbiorową do wybranej zmiennej, jeśli potrzebujesz oryginału nienaruszonego.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-12 15:45:25
UPDATE: zaktualizowałem porównanie z odpowiedzią @ sindri_baldur-używając wersji 1.12.6
. Zgodnie z wynikami, {[3] } jest przydatnym skrótem, ale jeśli wydajność ma znaczenie, należy trzymać się rozwiązania ..
lub with = FALSE
(patrz poniżej).
Najwyraźniej istnieje nowy sposób osiągnięcia tego od wersji 1.10.2.
library(data.table)
cols <- grep("bar|baz", names(mydt), value = TRUE)
mydt[, ..cols]
Wydaje się działać najszybciej z opublikowanych rozwiązań.
# Creating a large data.table with 100k rows, 32 columns
n <- 100000
foo_cols <- paste0("foo", 1:30)
big_dt <- data.table(bar = rnorm(n), baz = rnorm(n))
big_dt[, (foo_cols) := rnorm(n)]
# Methods
subsetting <- function(dt) {
subset(dt, select = grep("bar|baz", names(dt)))
}
usingSD <- function(dt) {
dt[, .SD, .SDcols = names(dt) %like% "bar|baz"]
}
usingWith <- function(dt) {
cols <- grep("bar|baz", names(dt), value = TRUE)
dt[, cols, with = FALSE]
}
usingDotDot <- function(dt) {
cols <- grep("bar|baz", names(dt), value = TRUE)
dt[, ..cols]
}
usingPatterns <- function(dt) {
dt[, .SD, .SDcols = patterns("bar|baz")]
}
# Benchmark
microbenchmark(
subsetting(big_dt), usingSD(big_dt), usingWith(big_dt), usingDotDot(big_dt), usingPatterns(big_dt),
times = 5000
)
#Unit: microseconds
# expr min lq mean median uq max neval
# subsetting(big_dt) 430 759 1672 1309 1563 82934 5000
# usingSD(big_dt) 547 951 1872 1461 1797 60357 5000
# usingWith(big_dt) 278 496 1331 1112 1304 62656 5000
# usingDotDot(big_dt) 289 483 1392 1117 1344 55878 5000
# usingPatterns(big_dt) 596 1019 1984 1518 1913 120331 5000
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-18 09:08:36
Istnieje również metoda subset
dla " data.table", więc zawsze możesz użyć czegoś takiego jak:
subset(mydt, select = grep("bar|baz", names(mydt)))
# bar baz
# 1: 2 3
# 2: 3 4
Okazuje się , że utworzenie startswith
typu funkcji dla "danych.tabela " nie jest bardzo prosta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:27
Od data.table v1.12.0
(Styczeń 2019) możesz zrobić:
mydt[, .SD, .SDcols = patterns("bar|baz")]
Z oficjalnej dokumentacji ?data.table
:
[...] możesz filtrować kolumny do włączenia w. SD zgodnie z regular wyrażenia via .SDcols=patterns (regex1, regex2, ...). W zestawie kolumny będą przecięciem kolumn zidentyfikowanych przez każdą wzorzec; wzorzec może być łatwo określony za pomocą / w wyrażeniu regularnym. Ty można również odwrócić wzór jak zwykle z .SDcols = !wzory(...).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-05 08:11:16
Proponuję ten jednowierszowy kod dla czytelności i wydajności.
mydt[,names(mydt) %like% "bar|baz", with=F]
Po odpowiedzi @ Janosdivenji:
Zobacz usingLike
w ostatnim wierszu
Unit: microseconds
expr min lq mean median uq max neval
subsetting(big_dt) 370.582 977.2760 1194.875 1016.4340 1096.9285 25750.94 5000
usingSD(big_dt) 554.330 1084.8530 1352.039 1133.4575 1226.9060 189905.39 5000
usingWith(big_dt) 238.481 832.7505 1017.051 866.6515 927.8460 22717.83 5000
usingDotDot(big_dt) 256.005 844.8770 1101.543 878.9935 936.6040 181855.43 5000
usingPatterns(big_dt) 569.787 1128.0970 1411.510 1178.2895 1282.2265 177415.23 5000
usingLike(big_dt) 262.868 852.5805 1059.466 887.3455 948.6665 23971.70 5000
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-09 19:25:21