Reformat data from long to wide

时间秒杀一切 提交于 2019-12-10 16:05:16

问题


How can I reformat this data to a wide format?

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

Desired output:

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

I have tried spread from tidyr but without success.


回答1:


data.table v 1.9.6+ allows you to pass more than one value.vars, so you can simply do

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



回答2:


You can try this:

> 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



回答3:


Here's a tidyr solution in a dplyr chain:

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


来源:https://stackoverflow.com/questions/36207623/reformat-data-from-long-to-wide

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!