2014-07-24 24 views
53

我有以下的伪数据:是否可以在tidyr中的多列上使用传播类似dcast?

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) 

是否有可能从包装tidyrspread做到这一点?

回答

53

一种选择是由paste加入了“产品”和“国家”列创建一个新的“Prod_Count”,删除与select这些列,然后使用spreadtidyr“长”到“宽”重塑。

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 

或者,我们可以通过使用unitetidyr(来自@甜菜根的评论)避免几个步骤和以前一样重塑。

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

是的,这是我首先想到的。但它不漂亮:) – mpiktas

+0

@mpiktas。我只能想到这种方法。可能是别人会拿出紧凑的代码:) - – akrun

+9

那么有'unite()',但它似乎只适用于数字数据(虽然目的虽然?)。 – beetroot

相关问题