This is what I have:
id<-c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2)
measure<-c("speed","weight","time","speed","weight","time","speed","weight","time",
"speed","weight","time","speed","weight","time","speed","weight","time")
value<-c(1.23,10.3,33,1.44,10.4,31,1.21,10.1,33,4.25,12.5,38,1.74,10.8,31,3.21,10.3,33)
testdf<-data.frame(id,measure,value)
This is what I want:
id<-c(1,1,1,2,2,2)
speed<-c(1.23,1.44,1.21,4.25,1.74,3.21)
weight<-c(10.3,10.4,10.1,12.5,10.8,10.3)
time<-c(33,31,33,37,31,33)
res<-data.frame(id,speed,weight,time)
The issue lies in that my variables speed weight and time are repeated. I can get it done with a for loop with if statements but its a major headache and not very efficient. This is my first post on stackoverflow ... long time user first time question ... thanks yall!
If you want to go the tidyverse route:
The R Cookbook is a great resource for these types of questions: http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/
Install reshape2 to help reformat data first
Then create another identifier to help organize data by three sequential rows at a time as you have in your desired dataset.
Bind separate datasets together row wise
Bind this new identifier to testdf column wise
Shape data from long to wide format
This is the resulting dataset:
You can remove the id2 variable if it is necessary using
Using
rowid
from data.table (very similar to @Kelli-Jean's answer):Or in one line
dcast(testdf, id + data.table::rowid(measure) ~ measure)
.Or without data.table, add like
testdf$r <- ave(testdf$id, testdf$meas, FUN = seq_along)
.Or if you're up for learning the data.table package:
UPDATE: Original answer as posted by @Frank:
Here is my solution