3

私はRの新しいユーザーですが、少し行き詰まっています。データは次のようになります。

dates        temp
01/31/2011    40
01/30/2011    34
01/29/2011    30
01/28/2011    52
01/27/2011    39
01/26/2011    37
...
01/01/2011    31

たとえば、40度未満で、開始日と終了日、およびそれが何日続くかについて、温度のみを取得したいと思います。

from         to           days
01/29/2011   01/30/2011     2
01/26/2011   01/27/2011     2

私はdifftimeで試しましたが、うまくいきませんでした。おそらく関数でうまくいくでしょう。

どんな助けでもいただければ幸いです。

4

3 に答える 3

3

私はこのようなことをします。ここで使用data.tableします。

df <- read.table(header=TRUE, text="dates        temp
01/31/2011    40
01/30/2011    34
01/29/2011    30
01/28/2011    52
01/27/2011    39
01/26/2011    37", stringsAsFactors=FALSE)

require(data.table)
dt <- data.table(df)
dt <- dt[, `:=`(date.form = as.Date(dates, format="%m/%d/%Y"), 
          id = cumsum(as.numeric(temp >= 40)))][temp < 40]
dt[, list(from=min(date.form), to=max(date.form), count=.N), by=id]

#    id       from         to count
# 1:  1 2011-01-29 2011-01-30     2
# 2:  2 2011-01-26 2011-01-27     2

アイデアは、最初に列をフォーマットdatesに変換して最初に列を作成することです。次に、位置を見つけ、それを使用して2以内の値のグループを作成するDate別の列。つまり、持っている場合は、が必要になります。つまり、to値の間のすべてが同じグループ(34、30-> 1および39、37-> 2)に属している必要があります。これを行った後、エントリを削除します。idtemp >= 40temp>=40c(40, 34, 30, 52, 39, 37)c(1,1,1,2,2,2)>= 40temp >= 40

次に、このグループで分割してからminmaxand length(.)(デフォルトではに格納されます.N)を取得できます。

于 2013-03-25T11:05:23.117 に答える
3

アルンほどエレガントではありませんdata.tableが、ここにbase解決策があります

DF <- read.table(text = "dates        temp\n01/31/2011    40\n01/30/2011    34\n01/29/2011    30\n01/28/2011    52\n01/27/2011    39\n01/26/2011    37", 
    header = TRUE, stringsAsFactors = FALSE)

DF$dates <- as.POSIXct(DF$dates, format = "%m/%d/%Y")
DF <- DF[order(DF$dates), ]
DF$ID <- cumsum(DF$temp >= 40)
DF2 <- DF[DF$temp < 40, ]

# Explanation split : split DF2 by DF2$ID 
# lapply : apply function on each list element given by split
# rbind : bind all the data together

do.call(rbind, lapply(split(DF2, DF2$ID), function(x) 
            data.frame(from = min(x$dates),  
                       to = max(x$dates), 
                       count = length(x$dates))))
##         from         to count
## 0 2011-01-26 2011-01-27     2
## 1 2011-01-29 2011-01-30     2
于 2013-03-25T11:42:03.350 に答える
3

最初にデータを読み込みます。 データを昇順に並べ替えたり、日付をクラスread.zooに変換したりするなど、詳細の多くを1行で処理します。結果の動物園オブジェクトがである"Date"場合は、温度と日付を示します。 zcoredata(z)time(z)

Lines <- "
dates        temp
01/31/2011    40
01/30/2011    34
01/29/2011    30
01/28/2011    52
01/27/2011    39
01/26/2011    37
"

library(zoo)
z <- read.zoo(text = Lines, header = TRUE, format = "%m/%d/%Y")

これらすべての核心は、rleどの計算lengthsを使用し、そこvaluesからすべての量を導き出すことができるかということです。

tt <- time(z)
with(rle(coredata(z) < 40), {
   to <- cumsum(lengths)[values]
   lengths <- lengths[values]
   from <- to - lengths + 1
   data.frame(from = tt[from], to = tt[to], days = lengths)
})

示されている入力データの最初の6行を使用すると、次のようになります。

       from          to   days
1 2011-01-26 2011-01-27      2
2 2011-01-29 2011-01-30      2
于 2013-03-25T15:53:59.290 に答える