2013-08-20 36 views
2

使用R腳本我從數據庫讀取值。這些值包含以下數據框。R-從數據框中查找缺失值並在該位置插入值

>values #return the output as follows 

ID   Date  Hour  Value 
1   2013-06-01 8   9 
2   2013-06-01 9   17 
3   2013-06-01 10   16 
4   2013-06-01 11   21 
5   2013-06-01 12   19 
6   2013-06-01 13   15 
7   2013-06-01 14   14 
8   2013-06-01 15   14 
9   2013-06-01 16   21 
10   2013-06-01 17   22 
11   2013-06-01 18   13 
12   2013-06-01 19   2 
13   2013-06-01 20   2 
14   2013-06-01 21   1 
15   2013-06-01 22   1 
16   2013-06-01 23   1 
17   2013-06-02 0   0 
18   2013-06-02 1   0 
19   2013-06-02 2   0 
20   2013-06-02 3   1 
21   2013-06-02 4   0 
22   2013-06-02 5   0 
23   2013-06-02 6   1 
24   2013-06-02 7   1 
25   2013-06-02 8   20 
26   2013-06-02 9   21 
27   2013-06-02 10   21 
28   2013-06-02 11   15 
29   2013-06-02 12   12 
30   2013-06-02 13   11 
31   2013-06-02 14   10 
32   2013-06-02 15   16 
33   2013-06-02 16   21 
34   2013-06-02 17   22 
35   2013-06-02 18   18 
36   2013-06-02 19   9 
37   2013-06-02 20   2 
38   2013-06-02 21   0 
39   2013-06-02 23   0 

我想找出數據框中丟失的小時數,並將0添加到該日期的丟失小時的值中。
例如:
從上述數據框, 2013-06-02日期的小時22缺失。我想在21和23小時之間插入一行,因爲

ID   Date  Hour  Value 
39   2013-06-02 22   0 

我該如何做到這一點?

我試過如下:

我有一個小時的清單,

>hours<-c(0:23) 
> hours #return as follows 
[1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 

>i<-values$Hour[1]+1 
>count<-nrow(values) 
>for(j in 1:count){ 
+h<-values$Hour[j] 
+hr<-hours[i] 
+if(h != hr) 
+{ 
+#write code to insert row 
+} 
+i<-i+1 
+if(i==25) 
+{ 
+i<-c(1) 
+} 
+} 

請幫我...

+1

您希望'id'用於'Date = 2013-06-01'前7項......即Hour = 0:7 ...? – Arun

+0

@Arun丟失數據 – Nandu

+0

然後,Date = 2013-06-02,Hour = 22'''''''''''''''''''''',而不是像你所示的那樣是39? – Arun

回答

4

對於每一天讓行0:23,轉換成數據幀,然後與您的數據合併。

您的數據:

values <- read.table(text="ID   Date  Hour  Value 
1   2013-06-01 8   9 
2   2013-06-01 9   17 
3   2013-06-01 10   16 
4   2013-06-01 11   21 
5   2013-06-01 12   19 
6   2013-06-01 13   15 
7   2013-06-01 14   14 
8   2013-06-01 15   14 
9   2013-06-01 16   21 
10   2013-06-01 17   22 
11   2013-06-01 18   13 
12   2013-06-01 19   2 
13   2013-06-01 20   2 
14   2013-06-01 21   1 
15   2013-06-01 22   1 
16   2013-06-01 23   1 
17   2013-06-02 0   0 
18   2013-06-02 1   0 
19   2013-06-02 2   0 
20   2013-06-02 3   1 
21   2013-06-02 4   0 
22   2013-06-02 5   0 
23   2013-06-02 6   1 
24   2013-06-02 7   1 
25   2013-06-02 8   20 
26   2013-06-02 9   21 
27   2013-06-02 10   21 
28   2013-06-02 11   15 
29   2013-06-02 12   12 
30   2013-06-02 13   11 
31   2013-06-02 14   10 
32   2013-06-02 15   16 
33   2013-06-02 16   21 
34   2013-06-02 17   22 
35   2013-06-02 18   18 
36   2013-06-02 19   9 
37   2013-06-02 20   2 
38   2013-06-02 21   0 
39   2013-06-02 23   0", header = TRUE, as.is=T) 

下面的代碼:

#make dummy data frame with all dates and hours 
dummy <- as.data.frame(
    cbind(
    sort(rep(unique(values$Date),24)), 
    rep(0:23,length(unique(values$Date))))) 
colnames(dummy) <- c("Date","Hour") 
dummy$Date <- as.character(dummy$Date) 
dummy$Hour <- as.numeric(as.character(dummy$Hour)) 

#merge with values dataframe 
values_v1 <- merge(dummy,values,all.x=T) 

#substitute NAs with 0(zero) 
values_v1[is.na(values_v1)] <- 0 
5

下面是使用data.table方式:

require(data.table) 
# install the package and then load if you don't have it already 
dt <- data.table(values, key="Hour") 
out <- merge(dt[, .SD[J(Hour[1]:23), roll=-Inf], by=Date, 
     .SDcols = c("Hour", "ID")], dt[, list(Date, Hour, Value)], 
     by=c("Date", "Hour"), all=TRUE)[is.na(Value), Value := 0L] 

說明:您的問題是有點不同的/因爲1)喲你似乎只想在缺失值發生在中間而不是其他任何地方時(開始或結束)填寫缺失值,並且2)你想用最後一個不缺失的ID(其中可以用roll完成),但是你想填充Value對應於缺少ID的0(這不能用roll完成)。

因此,這個想法是,首先通過使用roll=-Inf得到ID的缺失值。這是通過聲明來完成的:

dt[, .SD[J(Hour[1]:23), roll=-Inf], by=Date, .SDcols = c("Hour", "ID")] 

這是在將密鑰設置爲Hour之後。

現在,我們需要爲Value獲得一個NA,用於新添加的ID。所以,我們merge它回來dt(與ID刪除,因爲我們已經照顧它)。這是通過:

dt[, list(Date, Hour, Value)] 

一旦我們這些,我們merge列上Date, Hour和使用參數all=TRUE填補缺失值也是如此。最後,我們用Value替換NA爲0。

+0

我真的不明白這一點(我將不得不多花一點時間),但它很有用,所以對我有+1。酷碼! –

+0

@ SimonO101,哪一部分解釋不清楚(以便我可以嘗試更好地解釋它)? – Arun

+1

嗯,我現在不怎麼說'roll = -Inf'是如何開始的,但這不是你的解釋,沒有意義,這是我對'data.table'軟件包的理解還不夠好。這是我的問題,不是你的! –