2015-09-07 78 views
2

我有一個數據幀,如下ř更換NA與另一列值的組內的下一個值值

tmpdf <- data.frame(spaceNum=c(1,1,1,2,2,2,2), time.IN=c("2015-09-04 16:30", "2015-09-04 19:50", "2015-09-04 21:00", "2015-09-05 12:00", "2015 09-05 13:00", "2015 09-05 16:00", "2015 09-05 17:00"), time.OUT= c("2015-09-04 18:00", "NA", "NA","NA", "2015-09-05 13:21", "2015 09-05 16:48", "NA")) 

> tmpdf 
    spaceNum   time.IN   time.OUT 
1  1 2015-09-04 16:30 2015-09-04 18:00 
2  1 2015-09-04 19:50    NA 
3  1 2015-09-04 21:00    NA 
4  2 2015-09-05 12:00    NA 
5  2 2015 09-05 13:00 2015-09-05 13:21 
6  2 2015 09-05 16:00 2015 09-05 16:48 
7  2 2015 09-05 17:00    NA 
> 

我想的time.OUT NA值替換到的time.IN下一行值不是NULL並在相同的spaceNum組內。即,以下是我期待的結果。

spaceNum   time.IN   time.OUT 
    1  1 2015-09-04 16:30 2015-09-04 18:00 
    2  1 2015-09-04 19:50 2015-09-04 21:00 
    3  1 2015-09-04 21:00    NA 
    4  2 2015-09-05 12:00 2015-09-05 13:00 
    5  2 2015 09-05 13:00 2015-09-05 13:21 
    6  2 2015 09-05 16:00 2015 09-05 16:48 
    7  2 2015 09-05 17:00    NA 

這似乎dplyr或data.table可以做到這一點,我不得不尋找以前的問題,但是沒有找到這個合適的路要走。

這可能是專家R用戶的簡單問題,但對我來說,它已經讓我幾個小時了,並沒有找到好的解決方案。請幫幫我!!謝謝。

+0

您沒有帶提供了一個例子,當'time.IN'爲NULL,它應該如何處理 –

+0

是你的真實也類的數據列'factor'在您的示例數據? –

+0

@David,爲了簡化問題,我想只是將time.OUT保留爲NULL,如果time.IN的下一行值爲NULL。 –

回答

4

以下是可能的dplyr解決方案。這是ifelselead組合,而最終產品應該再次轉換爲as.POSIXct作爲信息丟失的結果,由於使用的ifelse

library(dplyr) 
tmpdf %>% 
    group_by(spaceNum) %>% 
    mutate(time.OUT = as.POSIXct(ifelse(is.na(time.OUT), lead(time.IN), time.OUT), origin = "1970-01-01")) 
# Source: local data frame [7 x 3] 
# Groups: spaceNum 
# 
# spaceNum    time.IN   time.OUT 
# 1  1 2015-09-04 16:30:00 2015-09-04 18:00:00 
# 2  1 2015-09-04 19:50:00 2015-09-04 21:00:00 
# 3  1 2015-09-04 21:00:00    <NA> 
# 4  2 2015-09-05 12:00:00 2015-09-05 13:00:00 
# 5  2 2015-09-05 13:00:00 2015-09-05 13:21:00 
# 6  2 2015-09-05 16:00:00 2015-09-05 16:48:00 
# 7  2 2015-09-05 17:00:00    <NA> 
+1

謝謝大衛,它的作品! –

1

試試這個,

首先用字符向量構建df不是因素。 然後把所有的NA值放在sapplysapply中的函數找到當天發生的NA後的下一個time.IN。並從原來的df拉他們。最後將它們分配給df的NA值。

tmpdf <- data.frame(spaceNum=c(1,1,1,2,2,2,2), 
time.IN=c("2015-09-04 16:30", "2015-09-04 19:50", "2015-09-04 21:00", "2015-09-05 12:00", "2015 09-05 13:00", "2015 09-05 16:00", "2015 09-05 17:00"), 
time.OUT= c("2015-09-04 18:00", NA, NA,NA, "2015-09-05 13:21", "2015 09-05 16:48", NA),stringsAsFactors = F) 

tmp<-tmpdf[unlist(
      sapply(which(is.na(tmpdf[,3])),function(x){ 
       if(tmpdf[x,1]==tmpdf[x+1,1] && !is.na(tmpdf[x,1]==tmpdf[x+1,1])) x+1 
       else NA 
       })), 2] 

tmpdf[which(is.na(tmpdf[,3])),3]<-tmp 

> tmpdf 
    spaceNum   time.IN   time.OUT 
1  1 2015-09-04 16:30 2015-09-04 18:00 
2  1 2015-09-04 19:50 2015-09-04 21:00 
3  1 2015-09-04 21:00    <NA> 
4  2 2015-09-05 12:00 2015 09-05 13:00 
5  2 2015 09-05 13:00 2015-09-05 13:21 
6  2 2015 09-05 16:00 2015 09-05 16:48 
7  2 2015 09-05 17:00    <NA> 
+1

@Tensibai我正在寫一些解釋。謝謝btw。 – vck

+0

@vck,同樣感謝你的支持sapply,BTW,它似乎有一個tydo,tmpdf [這是(is.na(tmpdf [,3])),3] < - kamil,「kamil」應該是「tmp 「, 對? –

+0

@簡志康是我更正了。 – vck

2

我們可以使用data.table做到這一點。在將'data.frame'轉換爲'data.table'(setDT(tmpdf))後,我們將factor'time'列轉換爲character類。在這裏,我假設NA s是真實的NA而不是字符串。按'spaceNum'分組,我們使用data.table的devel版本中的shift創建一個新的列'v1'。在'time.out'中將'time.OUT'值分配給對應於NA元素的'v1'。我們也可以將不需要的列「NULL」,即「V1」

library(data.table)#v1.9.5+ 
setDT(tmpdf)[, (2:3) :=lapply(.SD, as.character), .SDcols=2:3] 
tmpdf[, v1:=shift(time.IN, type='lead'), spaceNum][is.na(time.OUT), 
        time.OUT:= v1][, v1:= NULL] 
tmpdf 
# spaceNum   time.IN   time.OUT 
#1:  1 2015-09-04 16:30 2015-09-04 18:00 
#2:  1 2015-09-04 19:50 2015-09-04 21:00 
#3:  1 2015-09-04 21:00    NA 
#4:  2 2015-09-05 12:00 2015 09-05 13:00 
#5:  2 2015 09-05 13:00 2015-09-05 13:21 
#6:  2 2015 09-05 16:00 2015 09-05 16:48 
#7:  2 2015 09-05 17:00    NA 

注意到,在本例中的數據集,除了性格"NA",我們也有多種格式的「時間」欄。即2015 09-05 16:482015-09-05 13:21。如果我們需要轉換爲POSIXct,我們可以使用library(lubridate),因爲它可以採用多種格式。

library(lubridate) 
tmpdf[, (2:3) := lapply(.SD, ymd_hm), .SDcols=2:3] 
tmpdf 
# spaceNum    time.IN   time.OUT 
#1:  1 2015-09-04 16:30:00 2015-09-04 18:00:00 
#2:  1 2015-09-04 19:50:00 2015-09-04 21:00:00 
#3:  1 2015-09-04 21:00:00    <NA> 
#4:  2 2015-09-05 12:00:00 2015-09-05 13:00:00 
#5:  2 2015-09-05 13:00:00 2015-09-05 13:21:00 
#6:  2 2015-09-05 16:00:00 2015-09-05 16:48:00 
#7:  2 2015-09-05 17:00:00    <NA> 
+2

感謝akrun提供的data.table解決方案。 –

+0

@簡志康Thanks for the upvote。 – akrun

相關問題