設定
データフレームに文字列として保存された期間の列があります。それらを適切な時間オブジェクト、おそらくPOSIXltに変換したい。ほとんどの文字列は、このメソッドを使用して簡単に解析できます。
> data <- data.frame(time.string = c(
+ "1 d 2 h 3 m 4 s",
+ "10 d 20 h 30 m 40 s",
+ "--"))
> data$time.span <- strptime(data$time.string, "%j d %H h %M m %S s")
> data$time.span
[1] "2012-01-01 02:03:04" "2012-01-10 20:30:40" NA
欠落している期間はコード化され"--"
ており、変換する必要がありNA
ます。これは既に発生していますが、保持する必要があります。
課題は、文字列がゼロ値の要素を削除することです。したがって、目的の値2012-01-01 02:00:14
は string になります"1 d 2 h 14 s"
。ただし、この文字列はNA
単純なパーサーで解析されます。
> data2 <- data.frame(time.string = c(
+ "1 d 2 h 14 s",
+ "10 d 20 h 30 m 40 s",
+ "--"))
> data2$time.span <- strptime(data2$time.string, "%j d %H h %M m %S s")
> data2$time.span
[1] NA "2012-01-10 20:30:40" NA
質問
- 可能なすべての文字列形式を処理する「R Way」とは何ですか? おそらく、各要素を個別にテストして抽出してから、再結合しますか?
- POSIXlt は適切なターゲット クラスですか? 特定の開始時刻から自由な期間が必要なため、誤った年と月のデータ (
2012-01-
) を追加するのは面倒です。
解決
@mplourde は、日付形式のさまざまな条件のテストに基づいて、書式設定文字列を動的に作成することで、間違いなく正しい考えを持っていました。cut(Sys.Date(), breaks='years')
のベースラインとしてのの追加datediff
も良かったのですが、as.POSIXct()
注: R2.11 ベースを使用しています。これは後のバージョンで修正されている可能性があります。
の出力はas.POSIXct()
、日付コンポーネントが含まれているかどうかによって劇的に変化します。
> x <- "1 d 1 h 14 m 1 s"
> y <- "1 h 14 m 1 s" # Same string, no date component
> format (x) # as specified below
[1] "%j d %H h %M m %S s"
> format (y)
[1] "% H h % M %S s"
> as.POSIXct(x,format=format) # Including the date baselines at year start
[1] "2012-01-01 01:14:01 EST"
> as.POSIXct(y,format=format) # Excluding the date baselines at today start
[1] "2012-06-26 01:14:01 EDT"
したがって、difftime
関数の 2 番目の引数は次のようになります。
- 入力文字列に日のコンポーネントがある場合、現在の年の最初の日の開始
- 入力文字列に日のコンポーネントがない場合の現在の日の開始
cut
これは、関数の単位パラメーターを変更することで実現できます。
parse.time <- function (x) {
x <- as.character (x)
break.unit <- ifelse(grepl("d",x),"years","days") # chooses cut() unit
format <- paste(c(if (grepl("d", x)) "%j d",
if (grepl("h", x)) "%H h",
if (grepl("m", x)) "%M m",
if (grepl("s", x)) "%S s"), collapse=" ")
if (nchar(format) > 0) {
difftime(as.POSIXct(x, format=format),
cut(Sys.Date(), breaks=break.unit),
units="hours")
} else {NA}
}