2015-11-19 35 views
8

我有一個數據集,有進出的日期和時間。每一行都是進出設置,但有些是空白的。我可以用na.omit和一個很好的閱讀刪除空白(這是一個csv,na.strings=c("")作品在read.csv)。如何將某些部分空白時轉換日期或日期時間字段; na.omit失敗

當然,因爲現實世界從不喜歡本教程,有些時間只是日期,因此我的as.POSIXlt(Dataset$In,format="%m/%d/%Y %H:%M")在「僅限日期沒有時間」返回NA。

na.omit不會刪除這些行。所以問題是2

  1. 爲什麼不na.omit工作,或者我怎麼能得到它的工作?

  2. 更好,我怎樣才能將一列轉換爲日期和時間(在POSIX格式)沒有2次調用或在格式字符串中的某種可選參數? (或者甚至有可能?)。

這是日期和時間的示例。我無法分享真正的文件,1它是巨大的,2它是PII。

Id,In,Out 
1,8/15/2015 8:00,8/15/2015 17:00 
1,8/16/2015 8:04,8/16/2015 
1,8/17/2015 8:50,8/17/2015 18:00 
1,8/18/2015,8/18/2015 17:00 
2,8/15/2015,8/15/2015 13:00 
2,8/16/2015 8:00,8/16/2015 17:00 
3,8/15/2015 4:00,8/15/2015 11:00 
3,8/16/2015 9:00,8/16/2015 19:00 
3,8/17/2015,8/17/2015 17:00 
3,, 
4,, 
4,8/16/2015 6:00,8/16/2015 20:00 
+0

關於第二個問題:這些應該是什麼時間? '00:00'? – Roland

+0

關於第一個問題。 'POSIXlt'對象實際上是一個'list'。看看'unclass(DF $ In)'。修復很簡單。改用'POSIXct'。 POSIXlt是比POSIXct更好的選擇。 – Roland

+1

好吧,把'as.POSIXlt'改成'as.POSIXct',你就成了。 – Roland

回答

4
DF <- read.table(text = "Id,In,Out 
       1,8/15/2015 8:00,8/15/2015 17:00 
       1,8/16/2015 8:04,8/16/2015 
       1,8/17/2015 8:50,8/17/2015 18:00 
       1,8/18/2015,8/18/2015 17:00 
       2,8/15/2015,8/15/2015 13:00 
       2,8/16/2015 8:00,8/16/2015 17:00 
       3,8/15/2015 4:00,8/15/2015 11:00 
       3,8/16/2015 9:00,8/16/2015 19:00 
       3,8/17/2015,8/17/2015 17:00", header = TRUE, sep = ",", 
       stringsAsFactors = FALSE) #set this option during import 


DF$In[nchar(DF$In) < 13] <- paste(DF$In[nchar(DF$In) < 13], "0:00") 
DF$Out[nchar(DF$Out) < 13] <- paste(DF$Out[nchar(DF$Out) < 13], "0:00") 

DF$In <- as.POSIXct(DF$In, format = "%m/%d/%Y %H:%M", tz = "GMT") 
DF$Out <- as.POSIXct(DF$Out, format = "%m/%d/%Y %H:%M", tz = "GMT") 
# Id     In     Out 
#1 1 2015-08-15 08:00:00 2015-08-15 17:00:00 
#2 1 2015-08-16 08:04:00 2015-08-16 00:00:00 
#3 1 2015-08-17 08:50:00 2015-08-17 18:00:00 
#4 1 2015-08-18 00:00:00 2015-08-18 17:00:00 
#5 2 2015-08-15 00:00:00 2015-08-15 13:00:00 
#6 2 2015-08-16 08:00:00 2015-08-16 17:00:00 
#7 3 2015-08-15 04:00:00 2015-08-15 11:00:00 
#8 3 2015-08-16 09:00:00 2015-08-16 19:00:00 
#9 3 2015-08-17 00:00:00 2015-08-17 17:00:00 

na.omit因爲它被記錄,以不與POSIXlt對象一起工作「處理向量,矩陣和數據幀包括向量和矩陣(只)。」 (見help("na.omit"))。和在嚴格意義上,POSIXlt對象不是載體:

unclass(as.POSIXlt(DF$In)) 
#$sec 
#[1] 0 0 0 0 0 0 0 0 0 
# 
#$min 
#[1] 0 4 50 0 0 0 0 0 0 
# 
#$hour 
#[1] 8 8 8 0 0 8 4 9 0 
# 
#$mday 
#[1] 15 16 17 18 15 16 15 16 17 
# 
#$mon 
#[1] 7 7 7 7 7 7 7 7 7 
# 
#$year 
#[1] 115 115 115 115 115 115 115 115 115 
# 
#$wday 
#[1] 6 0 1 2 6 0 6 0 1 
# 
#$yday 
#[1] 226 227 228 229 226 227 226 227 228 
# 
#$isdst 
#[1] 0 0 0 0 0 0 0 0 0 
# 
#attr(,"tzone") 
#[1] "GMT" 

幾乎沒有任何理由,更喜歡POSIXlt超過POSIXct(這是一個整數,給出,因爲在內部原點的秒數,因此需要較少的存儲器)。

+0

真的希望我可以upvote 2次...這是一個很好的答案(你的知識是巨大的。) –

2

您已經給出了一些策略,將這些字符值帶入並處理「in-place」。我幾乎從不使用as.POSIXlt,因爲處理它返回的list-in-list結構有很多缺陷,特別是考慮到它與數據框的有效不兼容。下面是通過定義as - 方法確實在read. - 電平測試和脅迫的方法:

setOldClass("inTime", prototype="POSIXct") 
setAs("character", "inTime", 
     function(from) structure(ifelse(is.na(as.POSIXct(from, format="%m/%d/%Y %H:%M")), 
              as.POSIXct(from, format="%m/%d/%Y") , 
              as.POSIXct(from, format="%m/%d/%Y %H:%M") ), 
           class="POSIXct")) 

read.csv(text=txt, colClasses=c("numeric", 'inTime','inTime')) 
    Id     In     Out 
1 1 2015-08-15 08:00:00 2015-08-15 17:00:00 
2 1 2015-08-16 08:04:00 2015-08-16 00:00:00 
3 1 2015-08-17 08:50:00 2015-08-17 18:00:00 
4 1 2015-08-18 00:00:00 2015-08-18 17:00:00 
5 2 2015-08-15 00:00:00 2015-08-15 13:00:00 
6 2 2015-08-16 08:00:00 2015-08-16 17:00:00 
7 3 2015-08-15 04:00:00 2015-08-15 11:00:00 
8 3 2015-08-16 09:00:00 2015-08-16 19:00:00 
9 3 2015-08-17 00:00:00 2015-08-17 17:00:00 

需要的structure「信封」,因爲ifelse的相當奇怪的行爲,否則將返回一個數字而不是類的對象 - 'POSIXct'。

相關問題