是否有可能在tidyr中的多个列上使用扩展类似于dcast?

时间:2014-07-24 09:27:52

标签: r reshape2 tidyr

我有以下虚拟数据:

library(dplyr)
library(tidyr)
library(reshape2)
dt <- expand.grid(Year = 1990:2014, Product=LETTERS[1:8], Country = paste0(LETTERS, "I")) %>%   select(Product, Country, Year)
dt$value <- rnorm(nrow(dt))

我选择了两个产品国家组合

sdt <- dt %>% filter((Product == "A" & Country == "AI") | (Product == "B" & Country =="EI"))

我希望每个组合并排看到这些值。我可以使用dcast

执行此操作
sdt %>% dcast(Year ~ Product + Country)

是否可以使用 tidyr 包中的spread执行此操作?

3 个答案:

答案 0 :(得分:58)

一种选择是创建一个新的&#39; Prod_Count&#39;加入&#39;产品&#39;和国家&#39; paste之前的列,使用select删除这些列,然后重新排列&#39; long&#39;广泛的&#39;使用spread中的tidyr

 library(dplyr)
 library(tidyr)
 sdt %>%
 mutate(Prod_Count=paste(Product, Country, sep="_")) %>%
 select(-Product, -Country)%>% 
 spread(Prod_Count, value)%>%
 head(2)
 #  Year      A_AI       B_EI
 #1 1990 0.7878674  0.2486044
 #2 1991 0.2343285 -1.1694878

或者我们可以使用unite中的tidyr(来自@ beetroot&#39;评论)避免一些步骤,并像以前一样重塑。

 sdt%>% 
 unite(Prod_Count, Product,Country) %>%
 spread(Prod_Count, value)%>% 
 head(2)
 #   Year      A_AI       B_EI
 # 1 1990 0.7878674  0.2486044
 # 2 1991 0.2343285 -1.1694878

答案 1 :(得分:1)

对于当前的开发版本tidyr,可以通过一个函数调用(pivot_wider())来实现。

pivot_wider()(对口:pivot_longer())的工作方式与spread()类似。 但是,它提供了其他功能,例如使用多个键/名称列(和/或多个值列)。 为此,参数names_from(指示从哪个列中获取新变量的名称)可以采用多个列名称(此处为ProductCountry

library("tidyr")
packageVersion("tidyr")
#> [1] '0.8.3.9000'

sdt %>% 
    pivot_wider(id_cols = Year, names_from = c(Product, Country)) %>% 
    head(2)
#> # A tibble: 2 x 3
#>     Year   A_AI    B_EI
#>    <int>  <dbl>   <dbl>
#>  1  1990 -2.08  -0.113 
#>  2  1991 -1.02  -0.0546

另请参阅:https://tidyr.tidyverse.org/dev/articles/pivot.html

答案 2 :(得分:0)

Base R解决方案:

 # Concatenate grouping vector: 

dt$PC <- paste0(dt$Product, "_", dt$Country)

# Spread the vectors by year: 

dt2 <- reshape(dt[,c(!(names(dt) %in% c("Product", "Country")))],

               idvar = "Year",

               ids = unique(dt$Year),

               direction = "wide",

               timevar = "PC")

# Remove "value.", from the vector names:

names(dt2) <- gsub("value[.]", "", names(dt2))

数据:

dt <- expand.grid(Year = 1990:2014,

                  Product = LETTERS[1:8],

                  Country = paste0(LETTERS, "I"))

dt$value <- rnorm(nrow(dt))