Jak topić i odlewać ramki danych za pomocą dplyr?
Ostatnio robię wszystkie moje manipulacje danymi za pomocą dplyr i jest to doskonałe narzędzie do tego. Jednak nie jestem w stanie przetopić lub oddać ramki danych za pomocą dplyr. Jest na to jakiś sposób? Obecnie używam do tego celu reshape2.
Chcę' dplyr ' rozwiązanie dla:
require(reshape2)
data(iris)
dat <- melt(iris,id.vars="Species")
3 answers
Następcą reshape2
jest tidyr
. Odpowiednikami melt()
i dcast()
są odpowiednio gather()
i spread()
. Odpowiednikiem Twojego kodu będzie
library(tidyr)
data(iris)
dat <- gather(iris, variable, value, -Species)
Jeśli zaimportowałeś magrittr
możesz użyć operatora rury jak w dplyr
, tzn. napisać
dat <- iris %>% gather(variable, value, -Species)
Zauważ, że musisz jawnie określić nazwy zmiennych i wartości, w przeciwieństwie do melt()
. Dla mnie składnia gather()
jest dość wygodna, ponieważ możesz po prostu określić kolumny, które chcesz przekonwertować na długi format, lub określ te, które chcesz pozostać w nowej ramce danych, dodając przedrostek ' - ' (tak jak dla gatunków powyżej), który jest nieco szybszy do wpisania niż w melt()
. Jednak zauważyłem, że na moim komputerze przynajmniej tidyr
może być zauważalnie wolniejszy niż reshape2
.
Edit w odpowiedzi na komentarz @hadley ' s poniżej, zamieszczam kilka informacji o czasie porównując dwie funkcje na moim komputerze.
library(microbenchmark)
microbenchmark(
melt = melt(iris,id.vars="Species"),
gather = gather(iris, variable, value, -Species)
)
# Unit: microseconds
# expr min lq median uq max neval
# melt 278.829 290.7420 295.797 320.5730 389.626 100
# gather 536.974 552.2515 567.395 683.2515 1488.229 100
set.seed(1)
iris1 <- iris[sample(1:nrow(iris), 1e6, replace = T), ]
system.time(melt(iris1,id.vars="Species"))
# user system elapsed
# 0.012 0.024 0.036
system.time(gather(iris1, variable, value, -Species))
# user system elapsed
# 0.364 0.024 0.387
sessionInfo()
# R version 3.1.1 (2014-07-10)
# Platform: x86_64-pc-linux-gnu (64-bit)
#
# locale:
# [1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C
# [3] LC_TIME=en_GB.UTF-8 LC_COLLATE=en_GB.UTF-8
# [5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8
# [7] LC_PAPER=en_GB.UTF-8 LC_NAME=C
# [9] LC_ADDRESS=C LC_TELEPHONE=C
# [11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C
# attached base packages:
# [1] stats graphics grDevices utils datasets methods base
#
# other attached packages:
# [1] reshape2_1.4 microbenchmark_1.3-0 magrittr_1.0.1
# [4] tidyr_0.1
#
# loaded via a namespace (and not attached):
# [1] assertthat_0.1 dplyr_0.2 parallel_3.1.1 plyr_1.8.1 Rcpp_0.11.2
# [6] stringr_0.6.2 tools_3.1.1
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
2014-07-28 08:58:33
Ponadto, cast może być za pomocą tidyr::spread()
Przykład dla Ciebie
library(reshape2)
library(tidyr)
library(dplyr)
# example data : `mini_iris`
(mini_iris <- iris[c(1, 51, 101), ])
# melt
(melted1 <- mini_iris %>% melt(id.vars = "Species")) # on reshape2
(melted2 <- mini_iris %>% gather(variable, value, -Species)) # on tidyr
# cast
melted1 %>% dcast(Species ~ variable, value.var = "value") # on reshape2
melted2 %>% spread(variable, value) # on tidyr
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-12-13 01:31:36
Aby dodać do powyższych odpowiedzi używając przykładu @ Lovetoken mini_iris
(jest to zbyt skomplikowane dla komentarza) - dla tych nowicjuszy, którzy nie rozumieją, co rozumie się przez stopienie i odlewanie.
library(reshape2)
library(tidyr)
library(dplyr)
# example data : `mini_iris`
mini_iris <- iris[c(1, 51, 101), ]
# mini_iris
#Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 5.1 3.5 1.4 0.2 setosa
#51 7.0 3.2 4.7 1.4 versicolor
#101 6.3 3.3 6.0 2.5 virginica
Melt przyjmuje ramkę danych i rozszerza się do długiej listy wartości. Nie jest wydajny, ale może być przydatny, jeśli chcesz połączyć zestawy danych. Pomyśl o strukturze Lodowej bańki topniejącej na blacie i rozchodzącej się.
melted1 <- testiris %>% melt(id.vars = "Species")
> nrow(melted1)
[1] 12
head(melted1)
# Species variable value
# 1 setosa Sepal.Length 5.1
# 2 versicolor Sepal.Length 7.0
# 3 virginica Sepal.Length 6.3
# 4 setosa Sepal.Width 3.5
# 5 versicolor Sepal.Width 3.2
# 6 virginica Sepal.Width 3.3
Możesz zobaczyć, jak dane zostały teraz podzielone na wiele wierszy wartości. Nazwy kolumn są teraz tekstem w zmiennej kolumnie.
Casting będzie ponownie montowany z powrotem do danych.tabela lub dane.rama.
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-03-08 18:59:24