将数据从长到宽重新格式化

时间:2016-03-24 18:36:23

标签: r reshape2 tidyr

如何将此数据重新格式化为宽格式?

species val    price
setosa  5.1     3
setosa  4.9     3
setosa  4.7     3
setosa  4.6     2

期望的输出:

species val1 val2 val3 val4 price1 price2 price3 price4
setosa  5.1  4.9  4.7  4.6    3       3      3      2

我试过从tidyr传播,但没有成功。

3 个答案:

答案 0 :(得分:7)

data.table v 1.9.6+允许您传递多个value.vars,因此您只需执行

library(data.table)
dcast(setDT(df), species ~ val + price, value.var = c("val", "price"))
#    species val.1_4.6_2 val.1_4.7_3 val.1_4.9_3 val.1_5.1_3 price.1_4.6_2 price.1_4.7_3 price.1_4.9_3 price.1_5.1_3
# 1:  setosa         4.6         4.7         4.9         5.1             2             3             3             3

答案 1 :(得分:5)

你可以试试这个:

> d
     species val price
1     setosa 5.1     3
2     setosa 4.9     3
3     setosa 4.7     3
4     setosa 4.6     2
5 versicolor 5.1     3
6 versicolor 4.9     3
7 versicolor 4.7     3
8 versicolor 4.6     2

> t(sapply(split(d,d$species),function(x){unlist(x[,-1]) }))
           val1 val2 val3 val4 price1 price2 price3 price4
setosa      5.1  4.9  4.7  4.6      3      3      3      2
versicolor  5.1  4.9  4.7  4.6      3      3      3      2

答案 2 :(得分:1)

这是dplyr链中的tidyr解决方案:

library(dplyr)
library(tidyr)

dat <- data.frame(species = "setosa", val = c(5.1, 4.9, 4.7, 4.6), price = c(3,3,3,2))

out.df <- dat %>% mutate(row.n = row_number()) %>% 
    gather(var, value, -c(species, row.n)) %>%
    unite(col.n, c(var, row.n), sep = "") %>%
    mutate(col.n = factor(col.n, levels = unique(col.n))) %>% # preserve column order
    spread(col.n, value)

out.df
  species val1 val2 val3 val4 price1 price2 price3 price4
1  setosa  5.1  4.9  4.7  4.6      3      3      3      2