Reputation: 1296
I am just wondering if you could guide me to the right direction about how can I reshape a dataset based on a specific criteria to arrange by hours, for example, I have the follwing example dataset:
I am trying to reshape the dataset to look like this:
how can I proceed with this reshaping please? Many Thanks.
My sample data:
data = structure(list(date = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L), .Label = "Jan-97", class = "factor"), day = c(1L,
1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), hour = c(1L, 2L,
3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), Value = c(65L, 29L,
31L, 42L, 42L, 52L, 61L, 57L, 55L, 52L, 57L, 46L)), .Names = c("date",
"day", "hour", "Value"), class = "data.frame", row.names = c(NA,
-12L))
Upvotes: 1
Views: 768
Reputation: 28461
An update using dplyr
and tidyr
packages:
library(tidyr)
library(dplyr)
data %>% mutate(hour=paste0('hour', hour)) %>% spread(hour, Value)
# date day hour1 hour2 hour3 hour4
#1 Jan-97 1 65 29 31 42
#2 Jan-97 2 42 52 61 57
#3 Jan-97 3 55 52 57 46
Upvotes: 1
Reputation: 110034
This is a way to do it in base:
reshape(data, timevar = c("hour"), v.names = c("Value"),
idvar = c("date", "day"), direction = "wide")
EDIT: Like Brian used if want to retain the names use:
names(DF)[-c(1:2)] <- paste0("hour", 1:4)
rownames(DF)<- 1:nrow(DF)
DF
Yielding:
date day hour1 hour2 hour3 hour4
1 Jan-97 1 65 29 31 42
2 Jan-97 2 42 52 61 57
3 Jan-97 3 55 52 57 46
Upvotes: 3
Reputation: 9057
This can be solved using reshape
reshape(data, idvar=c('date','day'), direction='wide', timevar='hour')
Upvotes: 3
Reputation: 58845
This uses the reshape2
package. I am sure it can be done with the reshape
function, but I am not as facile with that.
library("reshape2")
dcast(data, date+day~hour, value.var="Value")
which gives
> dcast(data, date+day~hour, value.var="Value")
date day 1 2 3 4
1 Jan-97 1 65 29 31 42
2 Jan-97 2 42 52 61 57
3 Jan-97 3 55 52 57 46
If you don't like the names from that, you can change them afterwards.
widedata <- dcast(data, date+day~hour, value.var="Value")
names(widedata)[-(1:2)] <- paste0("hour",names(widedata[-(1:2)]))
so widedata
is:
> widedata
date day hour1 hour2 hour3 hour4
1 Jan-97 1 65 29 31 42
2 Jan-97 2 42 52 61 57
3 Jan-97 3 55 52 57 46
Upvotes: 5