2015-06-09 4 views
1

У меня есть кадр данных, как:Таблица недели до даты

> df 

    week month year x 
1 1-7 sep 2013 566 
2 8-14 sep 2013 65 
3 15-21 sep 2013 144 
4 22-28 sep 2013 455 
5 29-30 sep 2013 1212 

И нужно, чтобы преобразовать его в:

> df_out 
     date  x 
1 01/09/2013 80.86 
2 02/09/2013 80.86 
3 03/09/2013 80.86 
4 04/09/2013 80.86 
5 05/09/2013 80.86 
6 06/09/2013 80.86 
7 07/09/2013 80.86 
8 08/09/2013 9.29 
9 09/09/2013 9.29 
10 10/09/2013 9.29 
11 11/09/2013 9.29 
12 12/09/2013 9.29 
13 13/09/2013 9.29 
14 14/09/2013 9.29 

Объяснение: Неделя 1-7 сентября 2013 года имеет 566 единиц Икс. Я хочу построить временной ряд, который дает мне единицы для каждого дня недели (с 2013-09-01 по 2013-09-07), равные 566/7.

Примечание, который может быть рядом (например, строка 5 моего df), где у нас есть только 2 дня. Таким образом, значение x для 2013-09-29 будет 1212/2 = 606

Я попытался сделать это в Excel, построив начало и дату окончания для каждой строки df. Это разделитель недельного столбца на «-» и построение столбцов даты. Я могу сделать это в R, но потом я застрял.

данных:

df <- structure(list(week = c("1-7", "8-14", "15-21", "22-28", "29-30" 
), month = c("sep", "sep", "sep", "sep", "sep"), year = c(2013L, 
2013L, 2013L, 2013L, 2013L), x = c(566L, 65L, 144L, 455L, 1212L 
)), .Names = c("week", "month", "year", "x"), class = "data.frame", row.names = c(NA, 
-5L)) 
+0

Ваши даты правильно? Разве они не отличаются на 7 дней, а не на 1 день? Например, не 01/09/2013 80.86 02/09/2013 80.86 но 01/09/2013 80.86 ** 08 **/09/2013 80.86 и т. Д. – user1945827

+0

Нет, все в порядке. См. Ответ @ Robert –

+0

Кстати, я также сделал решение для Excel. Я найду время, чтобы опубликовать его здесь –

ответ

2

Попробуйте это:

dfl=split(df,1:nrow(df)) 
do.call(rbind,lapply(dfl,function(wd){ 
    d=as.numeric(unlist(strsplit(wd$week, "-", fixed = TRUE))) 
    days=d[1]:d[2] 
    date=as.Date(paste(wd$year,wd$month,days,sep="/"),"%Y/%b/%d") 
    x=round(rep(wd$x/length(days),length(days)),2) 
    data.frame(date,x) 
})) 
  date  x 
1.1 2013-09-01 80.86 
1.2 2013-09-02 80.86 
1.3 2013-09-03 80.86 
1.4 2013-09-04 80.86 
1.5 2013-09-05 80.86 
1.6 2013-09-06 80.86 
1.7 2013-09-07 80.86 
2.1 2013-09-08 9.29 
2.2 2013-09-09 9.29 
2.3 2013-09-10 9.29 
2.4 2013-09-11 9.29 
2.5 2013-09-12 9.29 
2.6 2013-09-13 9.29 
2.7 2013-09-14 9.29 
3.1 2013-09-15 20.57 
3.2 2013-09-16 20.57 
3.3 2013-09-17 20.57 
3.4 2013-09-18 20.57 
3.5 2013-09-19 20.57 
3.6 2013-09-20 20.57 
3.7 2013-09-21 20.57 
4.1 2013-09-22 65.00 
4.2 2013-09-23 65.00 
4.3 2013-09-24 65.00 
4.4 2013-09-25 65.00 
4.5 2013-09-26 65.00 
4.6 2013-09-27 65.00 
4.7 2013-09-28 65.00 
5.1 2013-09-29 606.00 
5.2 2013-09-30 606.00 
+0

Вы могли бы обобщить функцию для более чем 1 колонки? Я имею в виду, если бы у моего df были y, z, ... столбцы, такие как x (числовые) –

+1

Просто измените x для 'xyz = sapply (wd [-c (1: 3)], function (xs) round (rep (xs)/длина (дни), длина (дни)), 2)); data.frame (date, xyz) ' – Robert

+0

Отлично, отлично работает для моего' df' с 4k + строками. Но когда я пробую его с 40k + строками, 'dfl' (list) становится очень огромным, как 100Mb на рабочей области, и процесс тратит несколько минут в полном объеме –

Смежные вопросы