Using two packages from the tidyverse
:
newdat <- dat %>%
group_by(ID) %>%
mutate(n = row_number()) %>%
ungroup() %>%
gather(k, v, -ID, -n) %>%
unite(k, c(k, n), sep="") %>%
spread(k, v)
newdat
# # A tibble: 3 × 21
# ID DATE1 DATE10 DATE2 DATE3 DATE4 DATE5 DATE6
# * <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
# 1 9101001 11-04-2010 <NA> 11-10-2010 <NA> <NA> <NA> <NA>
# 2 9101002 28-12-2009 21-01-2013 31-03-2010 26-08-2010 13-01-2011 12-04-2011 08-12-2011
# 3 9101003 16-09-2008 <NA> 24-03-2009 15-03-2011 21-04-2011 <NA> <NA>
# # ... with 13 more variables: DATE7 <chr>, DATE8 <chr>, DATE9 <chr>, VALUE1 <chr>,
# # VALUE10 <chr>, VALUE2 <chr>, VALUE3 <chr>, VALUE4 <chr>, VALUE5 <chr>, VALUE6 <chr>,
# # VALUE7 <chr>, VALUE8 <chr>, VALUE9 <chr>
So this gets you the right columns, but not in the right order. If that's important:
newdat[c(1, 1L + order(
as.integer(gsub("[^0-9]", "", colnames(newdat[-1]))),
colnames(newdat[-1])
))]
# # A tibble: 3 × 21
# ID DATE1 VALUE1 DATE2 VALUE2 DATE3 VALUE3 DATE4 VALUE4 DATE5
# <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
# 1 9101001 11-04-2010 4 11-10-2010 4 <NA> <NA> <NA> <NA> <NA>
# 2 9101002 28-12-2009 104 31-03-2010 193 26-08-2010 130 13-01-2011 128 12-04-2011
# 3 9101003 16-09-2008 273 24-03-2009 311 15-03-2011 166 21-04-2011 62 <NA>
# # ... with 11 more variables: VALUE5 <chr>, DATE6 <chr>, VALUE6 <chr>, DATE7 <chr>,
# # VALUE7 <chr>, DATE8 <chr>, VALUE8 <chr>, DATE9 <chr>, VALUE9 <chr>, DATE10 <chr>,
# # VALUE10 <chr>
The c(1L, 1L + ...
stuff is to remove $ID
from consideration on the reordering. There are almost certainly other ways to reorder the columns.
Copyable data:
dat <- read.table(text='ID DATE VALUE
9101001 11-04-2010 4
9101001 11-10-2010 4
9101002 28-12-2009 104
9101002 31-03-2010 193
9101002 26-08-2010 130
9101002 13-01-2011 128
9101002 12-04-2011 27
9101002 08-12-2011 18
9101002 17-07-2012 85
9101002 10-10-2012 86
9101002 19-12-2012 4
9101002 21-01-2013 31
9101003 16-09-2008 273
9101003 24-03-2009 311
9101003 15-03-2011 166
9101003 21-04-2011 62', header=TRUE, stringsAsFactors=FALSE)