2017-07-03 3 views
3

その他の質問は開始日と終了日を中心に行われています。 (私の質問は、上の労働者の数と取引を作成し、この具体的な例。私は1つの日付列を持っていると私は毎日カウントに等しくない日付範囲を変換したいという点で異なっている例 Given start date and end date, reshape/expand data for each day between (each day on a row) Expand rows by date range using start and end date日付のベクトルのみを指定すると、(不等な)日付点の間にデータを展開します

については、以下を参照してください一度、現場の人々の様々な乗組員は次のように提供する簡単なデータフレームである

異なる日付に来る:。

dd <- data.frame(date=as.Date(c("1999-03-22","1999-03-29","1999-04-08")),work=c(43,95,92),cumwork=c(43,138,230)) 

私は、データが次のようになりたいと思います:

dw <- data.frame(date=c(seq(as.Date("1999-03-22"),as.Date("1999-04-10"),by= "day")), 
     work=c(rep(43,7),rep(95,10),rep(92,3)), 
     cumwork=c(rep(43,7),rep(138,10),rep(230,3))) 

私はしばらくこのことに固執しています。どんな助けもありがとう!

UPDATE(7/5/2017):@Scarabeeが指摘しているように、データフレーム 'dd'の日付は日付形式である必要があります。この

+0

は、このリンクをチェックhttps://stackoverflow.com/questions/21008166/added-missing-dates-to-dataframe – Wen

答えて

1

可能な方法を反映するために、コードを更新しました:

まず、あなたが興味を持っている日付のシーケンスを作成して1列のデータフレームのように: は

次に、と

v <- data.frame(date = seq(min(dd$date), as.Date("1999-04-10"), by="day")) 
参加ごオリジナルのデータフレームと dplyrzooを使用して、インスタンスの欠損値を埋める:

library(dplyr) 
library(zoo) 

v %>% 
    left_join(dd, by = "date") %>% 
    na.locf 

NB:データフレームddには実際に日付が含まれていて、要因は含まれていないと思われます。

dd <- data.frame(date=as.Date(c("1999-03-22","1999-03-29","1999-04-08")),work=c(43,95,92),cumwork=c(43,138,230)) 
+0

na.locf関数は本当に素晴らしかったです!そのコマンドについては決して知らなかった。すべてのソリューションは機能しましたが、コード内の簡単なシンプルさと配管のために、最終的に@Scarabeeを選択します。 – EDennnis

0

ベースR(及びzooパッケージ)と同様のソリューション、:

dd$date <- as.Date(as.character(dd$date)) 
my.seq <- data.frame(date=seq.Date(from=range(dd$date)[1], to=range(dd$date)[2], by="day")) 
output <- merge(my.seq, dd, all.x=TRUE) 
output <- zoo::na.locf(output) 

あなたが最初の日付形式に日付を変換する必要があります。次に完全な日付のベクトルを別々に作成し、元のデータとマージします。最終的には、 "last observation carry forward"アルゴリズムを実行します。ここで

0

は本当に速い純粋なベースRソリューションです:

ExpandDates <- function(df, lastColRepeat) { 
    myDiff <- diff(df$date) 
    dfOut <- data.frame(df$date[1] + 0:(sum(myDiff) + lastColRepeat - 1L), 
        stringsAsFactors=FALSE) 
    myDiff <- c(myDiff, lastColRepeat) 
    for (i in 2:3) {dfOut[,i] <- rep(df[ ,i], times = myDiff)} 
    names(dfOut) <- names(df) 
    dfOut 
} 

最後の引数は、最後の値が繰り返されるべき回数を決定することです。この値を与える元のdata.frameには何もありません。私はまた、 "日付"フィールドが実際に@スカラビによって指摘された日付であると仮定しています。

ここ

は、いくつかのテストデータです:

set.seed(123) 
workVec <- sample(5000, 3000) 
testDF <- data.frame(date = as.Date(sort(sample(12000, 3000)), 
            origin = "1970-01-01"), work = workVec, 
                cumwork = cumsum(workVec)) 

DplyrTest <- function(dd) { ## from @Scarabee 
    v <- data.frame(date = seq(min(dd$date), max(dd$date), by="day")) 
    v %>% 
     left_join(dd, by = "date") %>% 
     na.locf 
} 

a <- ExpandDates(testDF, 1) 
b <- DplyrTest(testDF) 

平等のためのテスト:

identical(a$cumwork, as.integer(b$cumwork)) 
[1] TRUE 
identical(a$work, as.integer(b$work)) 
[1] TRUE 
identical(a$date, as.Date(b$date)) 
[1] TRUE 

ベンチマーク:

library(microbenchmark) 
microbenchmark(DplyrTest(testDF), ExpandDates(testDF,1)) 
Unit: milliseconds 
        expr  min  lq  mean median  uq  max neval cld 
    DplyrTest(testDF) 80.909303 84.337006 91.315057 86.320883 88.818739 173.69395 100 b 
ExpandDates(testDF, 1) 1.122384 1.208184 2.521693 1.355564 1.486317 72.23444 100 a 
関連する問題