YungBoy
YungBoy

Reputation: 235

R converting a single week row, to 7 day rows

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

Answers (3)

Abdou
Abdou

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

mtoto
mtoto

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

eipi10
eipi10

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

Related Questions