0

1 が午前 1 時に対応し、23 が午後 11 時に対応し、24 が 1 日の終わりを意味するように、時間 (文字形式) を 10 進形式に変換する関数を作成しようとしています。

これを行う 2 つの関数を次に示します。ここでは、1 つの関数がベクトル化し、他の関数がベクトル化します

time2dec <- function(time0)
{
time.dec <-as.numeric(substr(time0,1,2))+as.numeric(substr(time0,4,5))/60+(as.numeric(substr(time0,7,8)))/3600
return(time.dec)
}

time2dec1 <- function(time0)
{
time.dec <-as.numeric(strsplit(time0,':')[[1]][1])+as.numeric(strsplit(time0,':')[[1]][2])/60+as.numeric(strsplit(time0,':')[[1]][3])/3600
return(time.dec)
}

これは私が得るものです...

times <- c('12:23:12','10:23:45','9:08:10')

#>time2dec(times)
[1] 12.38667 10.39583       NA
Warning messages:
1: In time2dec(times) : NAs introduced by coercion
2: In time2dec(times) : NAs introduced by coercion

#>time2dec1(times)
[1] 12.38667

時間の代わりにtime2dec抽出するため、最後の要素に NA を与えるベクトル化されたものを知っています。それが私が作成した理由ですが、ベクトル化されていない理由がわかりません。9:9time2dec1

また、私がやろうとしていることを実行するためのより良い機能を手に入れることにも興味があります. これは私の質問の一部を説明していますが、私がしようとしていることを行う手がかりを提供していません。

4

4 に答える 4

4

車輪を再発明しようとしないでください。

times1 <- difftime(as.POSIXct(times, "%H:%M:%S", tz="GMT"),
                   as.POSIXct("0:0:0", "%H:%M:%S", tz="GMT"), 
                   units="hours")
#Time differences in hours
#[1] 12.386667 10.395833  9.136111

as.numeric(times1)
#[1] 12.386667 10.395833  9.136111
于 2014-04-19T20:55:17.907 に答える
2
 as.numeric( strptime(times, "%H:%M:%S")-strptime(Sys.Date(), "%Y-%m-%d" ))
[1] 12.386667 10.395833  9.136111

基本的にローランドのものと同じですが、いくつかの手順を省略しており、できる限り使用しないようにしdifftimeています。関数やクラスをよく理解していないため、バグが多すぎました...または何か。そして、私がそれをローランドのものと比較して時間を計ったとき、彼はより速かった. しかたがない。

@G.Grothendieck の努力をエミュレートする (そして本質的に彼のエレガントなストラップ ソリューションと同様に動作します:

num <- apply( matrix(scan(text=gsub(":", " ", ch), what=numeric(0)),nrow=3), 2, 
                 function(x) x[1]+x[2]/60 +x[3]/3600 )
#Read 9 items
num
#[1] 12.386667 10.395833  9.136111

そして、これは実際に元の質問に答えます:

 num <- sapply( strsplit(ch, ":"), function(x){ x2 <- as.numeric(x);
                                                x2[1]+x2[2]/60 +x2[3]/3600})
 num
#[1] 12.386667 10.395833  9.136111
于 2014-04-19T21:21:28.110 に答える
2

以下では、このテスト ベクトルを使用します。

ch <- c('12:23:12','10:23:45','9:08:10')

1)質問の解決策を修正するには、先頭に 0 を追加し、3 桁の文字列を最後の 2 桁に置き換えます。

num.substr <- function(...) as.numeric(substr(...))
time2dec <- function(time0) {
    t0 <- sub("\\d(\\d\\d)", "\\1", paste0(0, time0))
    num.substr(t0, 1, 2) + num.substr(t0, 4, 5) / 60 + num.substr(t0, 7, 8) / 3600
}

time2dec(ch)
## [1] 12.386667 10.395833  9.136111

2)strapply gsubfn パッケージを使用すると、文字列の解析が少し簡単になります。

strapply(ch, "^(.?.):(..):(..)", 
   ~ as.numeric(h) + as.numeric(m)/60 + as.numeric(s)/36000,
   simplify = c)
## [1] 12.383667 10.384583  9.133611

3)文字列操作をコロンを削除するだけに減らし、結果の文字列を数値に変換して、数値的に操作できるようにすることができます。

num <- as.numeric(gsub(":", "", ch))
num %/% 10000 + num %% 10000 %/% 100 / 60 + num %% 100 / 3600
## [1] 12.386667 10.395833  9.136111

4) chron パッケージには、"times"時間を 1 日の端数として内部的に表すクラスがあります。それを時間に変換すると、簡単な解決策が得られます。

library(chron)

24 * as.numeric(times(ch))
## [1] 12.386667 10.395833  9.136111

ADDEDさらにソリューションを追加しました。

于 2014-04-19T21:34:22.557 に答える
1

以下はあなたが望むことをします

sapply(strsplit(times, ":"), function(d) {
  sum(as.numeric(d)*c(1,1/60,1/3600))
})

ステップバイステップ:

strsplit(times, ":")

文字ベクトルのリストを返します。各文字ベクトルには、時刻の 3 つの部分 (時、分、秒) が含まれています。リスト内の各要素を数値に変換します。このために、各要素に関数を適用し、その結果をベクトルに入れる必要がありますsapply

sapply(strsplit(times, ":", function(d) {
})

機能は。まず、 を使用して文字値を numeris 値に変換する必要がありますas.numeric。最初の要素を 1 で、2 番目の要素を 1/60 で、3 番目の要素を 1/3600 で乗算し、結果を加算します (これには を使用しますsum)。その結果

sapply(strsplit(times, ":"), function(d) {
  sum(as.numeric(d)*c(1,1/60,1/3600))
})
于 2014-04-19T20:54:03.957 に答える