Подтвердить что ты не робот

Как расплавить и отбросить данные с помощью dplyr?

Недавно я делаю все свои манипуляции с данными с помощью dplyr, и это отличный инструмент для этого. Однако я не могу расплавить или применить кадр данных с помощью dplyr. Есть ли способ сделать это? Прямо сейчас я использую reshape2 для этой цели.

Я хочу "dplyr" для:

require(reshape2)
data(iris)
dat <- melt(iris,id.vars="Species")
4b9b3361

Ответ 1

Преемником reshape2 является tidyr. Эквивалент melt() и dcast() равен gather() и spread() соответственно. Тогда эквивалент вашего кода будет

library(tidyr)
data(iris)
dat <- gather(iris, variable, value, -Species)

Если вы импортировали magrittr, вы можете использовать оператор трубы, например, в dplyr, т.е. написать

dat <- iris %>% gather(variable, value, -Species)

Обратите внимание, что вам нужно указать имена переменных и значений явно, в отличие от melt(). Я считаю, что синтаксис gather() довольно удобен, потому что вы можете просто указать столбцы, которые хотите преобразовать в длинный формат, или указать те, которые вы хотите оставить в новом фрейме данных, префикс их с помощью "-" (так же, как для видов выше), который немного быстрее, чем в melt(). Тем не менее, я заметил, что на моей машине, по крайней мере, tidyr может быть заметно медленнее, чем reshape2.

Изменить. В ответ на комментарий @hadley ниже я размещаю некоторую информацию о времени, сравнивая две функции на моем ПК.

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   

Ответ 2

Кроме того, cast может использовать tidyr::spread()

Пример для вас

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

Ответ 3

Чтобы добавить к ответам выше, используя пример @Lovetoken mini_iris (это слишком сложно для комментария) - для тех новичков, которые не понимают, что подразумевается под действием расплава и литья.

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

Расплав принимает блок данных и расширяется в длинный список значений. Неэффективен, но может быть полезен, если вам нужно объединить наборы данных. Подумайте о структуре плавки icecube на столе и расширении.

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

Вы можете видеть, как данные теперь разбиты на многие строки значений. Имена столбцов теперь являются текстом внутри столбца переменной.

литье снова будет собрано в data.table или data.frame.