Reputation: 235
I've seen a few similar examples and threads online this morning, but nothing I could find quite like my particular case. I have a dataframe that looks something like this:
Week Income Views Partner
09/07/15 2000 345 Bob
09/07/15 460 11980 Jane
08/31/15 304 678 Mark
What I need is for each "week row" to be replicated for each day within the week. You don't need to worry about how to alter the other variables so that they are divided by 7, I can perform those operations without assistance. What I am having trouble with is expanding the week row to 7 rows total that describe each day within the week, like so:
Week Income Views Partner
09/07/15 2000 345 Bob
09/08/15 2000 345 Bob
09/09/15 2000 345 Bob
09/10/15 2000 345 Bob
09/11/15 2000 345 Bob
09/12/15 2000 345 Bob
09/13/15 2000 345 Bob
09/07/15 460 11980 Jane
09/08/15 460 11980 Jane
09/09/15 460 11980 Jane
09/10/15 460 11980 Jane
09/11/15 460 11980 Jane
09/12/15 460 11980 Jane
09/13/15 460 11980 Jane
08/31/15 304 678 Mark
09/01/15 304 678 Mark
09/02/15 304 678 Mark
09/03/15 304 678 Mark
09/04/15 304 678 Mark
09/05/15 304 678 Mark
09/06/15 304 678 Mark
Like I said all other data points can be left at NA (I can na.locf easily) or just have them copied down the columns.
Thanks for the help in advance!
Upvotes: 3
Views: 90
Reputation: 13274
Another solution:
dput(testtable)
structure(list(Week = c("09/07/15", "09/07/15", "08/31/15"),
Income = c(2000L, 460L, 304L), Views = c(345L, 11980L, 678L
), Partner = c("Bob", "Jane", "Mark")), .Names = c("Week",
"Income", "Views", "Partner"), class = "data.frame", row.names = c(NA,
-3L))
week <- c(seq(as.Date("2015/07/15"), by = "day",
length.out = 7),seq(as.Date("2015/07/15"), by = "day",
length.out = 7), seq(as.Date("2015/08/15"),
by = "day", length.out = 7))
df <- cbind(week,testtable[rep(seq_len(nrow(testtable)), each=7),2:ncol(testtable)])
df
week Income Views Partner
1 2015-07-15 2000 345 Bob
2 2015-07-16 2000 345 Bob
3 2015-07-17 2000 345 Bob
4 2015-07-18 2000 345 Bob
5 2015-07-19 2000 345 Bob
6 2015-07-20 2000 345 Bob
7 2015-07-21 2000 345 Bob
8 2015-07-15 460 11980 Jane
9 2015-07-16 460 11980 Jane
10 2015-07-17 460 11980 Jane
11 2015-07-18 460 11980 Jane
12 2015-07-19 460 11980 Jane
13 2015-07-20 460 11980 Jane
14 2015-07-21 460 11980 Jane
15 2015-08-15 304 678 Mark
16 2015-08-16 304 678 Mark
17 2015-08-17 304 678 Mark
18 2015-08-18 304 678 Mark
19 2015-08-19 304 678 Mark
20 2015-08-20 304 678 Mark
21 2015-08-21 304 678 Mark
Upvotes: 4
Reputation: 24178
Expanding on @epi10 's answer, we can alternatively use the following data.table
approach:
library(data.table)
dat1 <- setDT(dat)[rep(seq_len(nrow(dat)), each=7),][,Day:=seq(min(Week),min(Week)+7,1),by=Partner]
# Yields
dat1
Week Income Views Partner Day
1: 2015-09-07 2000 345 Bob 2015-09-07
2: 2015-09-07 2000 345 Bob 2015-09-08
3: 2015-09-07 2000 345 Bob 2015-09-09
4: 2015-09-07 2000 345 Bob 2015-09-10
5: 2015-09-07 2000 345 Bob 2015-09-11
6: 2015-09-07 2000 345 Bob 2015-09-12
7: 2015-09-07 2000 345 Bob 2015-09-13
8: 2015-09-07 460 11980 Jane 2015-09-07
9: 2015-09-07 460 11980 Jane 2015-09-08
10: 2015-09-07 460 11980 Jane 2015-09-09
11: 2015-09-07 460 11980 Jane 2015-09-10
12: 2015-09-07 460 11980 Jane 2015-09-11
13: 2015-09-07 460 11980 Jane 2015-09-12
14: 2015-09-07 460 11980 Jane 2015-09-13
15: 2015-08-31 304 678 Mark 2015-08-31
16: 2015-08-31 304 678 Mark 2015-09-01
17: 2015-08-31 304 678 Mark 2015-09-02
18: 2015-08-31 304 678 Mark 2015-09-03
19: 2015-08-31 304 678 Mark 2015-09-04
20: 2015-08-31 304 678 Mark 2015-09-05
21: 2015-08-31 304 678 Mark 2015-09-06
Week Income Views Partner Day
Upvotes: 2
Reputation: 93761
The code below uses mapply
to create the new rows for each combination of Week
and Partner
. Then, we wrap it in do.call(rbind, ...)
to put each subgroup back together into a single data frame. I've left the original Week
column in the final output just for illustation, but that can be removed.
# Sample data
dat = read.table(text=" Week Income Views Partner
09/07/2015 2000 345 Bob
09/07/2015 460 11980 Jane
08/31/2015 304 678 Mark" , header=TRUE, stringsAsFactors=FALSE)
dat$Week = as.Date(dat$Week, "%m/%d/%Y")
newdat = do.call(rbind,
mapply(function(w,p) {
data.frame(Day=seq(w, w+6, 1), dat[dat$Week==w & dat$Partner==p, ])
}, dat$Week, dat$Partner, SIMPLIFY=FALSE))
newdat
Day Week Income Views Partner
1 2015-09-07 2015-09-07 2000 345 Bob
2 2015-09-08 2015-09-07 2000 345 Bob
3 2015-09-09 2015-09-07 2000 345 Bob
4 2015-09-10 2015-09-07 2000 345 Bob
5 2015-09-11 2015-09-07 2000 345 Bob
6 2015-09-12 2015-09-07 2000 345 Bob
7 2015-09-13 2015-09-07 2000 345 Bob
8 2015-09-07 2015-09-07 460 11980 Jane
9 2015-09-08 2015-09-07 460 11980 Jane
10 2015-09-09 2015-09-07 460 11980 Jane
11 2015-09-10 2015-09-07 460 11980 Jane
12 2015-09-11 2015-09-07 460 11980 Jane
13 2015-09-12 2015-09-07 460 11980 Jane
14 2015-09-13 2015-09-07 460 11980 Jane
15 2015-08-31 2015-08-31 304 678 Mark
16 2015-09-01 2015-08-31 304 678 Mark
17 2015-09-02 2015-08-31 304 678 Mark
18 2015-09-03 2015-08-31 304 678 Mark
19 2015-09-04 2015-08-31 304 678 Mark
20 2015-09-05 2015-08-31 304 678 Mark
21 2015-09-06 2015-08-31 304 678 Mark
Upvotes: 4