2013-02-20 3 views
3

У меня есть данные, которые имеют два параметра, это данные/время и поток. Данные потока являются прерывистым потоком. Предположим, что временами происходит нулевой поток, и внезапно начинается поток, и на какое-то время будут ненулевые значения, а затем поток снова будет равен нулю. Я хочу понять, когда возникают ненулевые значения и как долго длится каждый ненулевой поток. Я приложил образец данных в этом месте https://www.dropbox.com/s/ef1411dq4gyg0cm/sampledataflow.csvНайти ненулевые значения и частоту этих значений в R

Данные - 1 минута данных.

я был в состоянии импортировать данные в R следующим образом:

flow <- read.csv("sampledataflow.csv") 
summary(flow) 
names(flow) <- c("Date","discharge") 
flow$Date <- strptime(flow$Date, format="%m/%d/%Y %H:%M") 
sapply(flow,class) 
plot(flow$Date, flow$discharge,type="l") 

Я сделал сюжет, чтобы увидеть распределение, но не может получить подсказку, где начать, чтобы получить частоту каждого ненулевых значений. Я хотел бы видеть таблицу результатов следующим образом:

Date Duration in Minutes 

Пожалуйста, дайте мне знать, если я здесь не ясен. Благодарю.

Дополнительная информация:

Я думаю, что мы должны проверить ненулевое значение первого, а затем найти сколько не нулевое значение там непрерывно, прежде чем он достигнет нулевого значения снова есть. То, что я хочу понять, это длительность выпуска потока. Напр. за один день может быть несколько выпусков, и я хочу отметить, в какое время начался выпуск и как долго он продолжался до того, как он достиг нулевого значения. Надеюсь, это объяснит проблему немного лучше.

+1

Выполнить Длина кодирование с использованием 'rle'? например, 'rle (flow $ discharge)'? – mnel

+0

Ваши данные состоят всего из 33 тысяч нечетных значений. Rest имеют 'Timestamp =" "' и 'flow = NA' – Arun

+0

Arun, это всего лишь образец, я не загрузил все данные. На самом деле, у меня около 230 тыс. Данных. Я добавил дополнительную информацию о своем оригинальном посте. –

ответ

3

Первое заключается в том, что у вас слишком много NA в ваши данные. Если вы хотите заглянуть в него. Если я правильно понял, вам нужно подсчитать количество непрерывных 0, за которыми следуют непрерывные не нули, нули, non-zeros и т. Д. Для каждой даты.

Конечно, это можно сделать с помощью rle, что также упоминается @mnel под комментариями. Но есть немало уловов.

Во-первых, я организую данные с не-NA записей:

flow <- read.csv("~/Downloads/sampledataflow.csv") 
names(flow) <- c("Date","discharge") 
flow <- flow[1:33119, ] # remove NA entries 

# format Date to POSIXct to play nice with data.table 
flow$Date <- as.POSIXct(flow$Date, format="%m/%d/%Y %H:%M") 

Далее я создам Date колонка:

flow$g1 <- as.Date(flow$Date) 

Наконец, я предпочитаю использовать data.table. Итак, вот решение, использующее его.

# load package, get data as data.table and set key 
require(data.table) 
flow.dt <- data.table(flow) 
# set key to both "Date" and "g1" (even though, just we'll use just g1) 
# to make sure that the order of rows are not changed (during sort) 
setkey(flow.dt, "Date", "g1") 
# group by g1 and set data to TRUE/FALSE by equating to 0 and get rle lengths 
out <- flow.dt[, list(duration = rle(discharge == 0)$lengths, 
     val = rle(discharge == 0)$values + 1), by=g1][val == 2, val := 0] 

> out # just to show a few first and last entries 

#    g1 duration val 
# 1: 2010-05-31  120 0 
# 2: 2010-06-01  722 0 
# 3: 2010-06-01  138 1 
# 4: 2010-06-01  32 0 
# 5: 2010-06-01  79 1 
# ---       
# 98: 2010-06-22  291 1 
# 99: 2010-06-22  423 0 
# 100: 2010-06-23  664 0 
# 101: 2010-06-23  278 1 
# 102: 2010-06-23  379 0 

Так, например, для 2010-06-01, есть 722 0's следуют 138 non-zeros, а затем 32 0's с последующим 79 non-zeros и так далее ...

+0

@Jdbaba, это решает вашу проблему? – Arun

+0

@ Arun: Большое вам спасибо за этот ответ. Да, это определенно решает мою проблему, чтобы найти продолжительность каждого нулевого и ненулевого. Другим приятным дополнением были бы средние значения нулей и ненулевых значений на такой длительности, если это было возможно. Спасибо. –

+0

Я думаю, что это отвечает на ваш вопрос. Получение среднего является простым, и я оставлю его вам. – Arun

2

Я выглядел маленький образец из первых двух дней

> do.call(cbind, tapply(flow$discharge, as.Date(flow$Date), function(x) table(x > 0))) 
     2010-06-01 2010-06-02 
FALSE  1223  911 
TRUE   217  529 # these are the cumulative daily durations of positive flow. 

Вы можете захотеть это транспонированным в этом случае функция т() удастся. Или вы можете использовать rbind.

Если этого нужно просто wante количества проточной Postive минут, это будет работать:

tapply(flow$discharge, as.Date(flow$Date), function(x) sum(x > 0, na.rm=TRUE) ) 
#-------- 
2010-06-01 2010-06-02 2010-06-03 2010-06-04 2010-06-05 2010-06-06 2010-06-07 2010-06-08 
     217  529  417  463   0   0  263  220 
2010-06-09 2010-06-10 2010-06-11 2010-06-12 2010-06-13 2010-06-14 2010-06-15 2010-06-16 
     244  219  287  234   31  245  311  324 
2010-06-17 2010-06-18 2010-06-19 2010-06-20 2010-06-21 2010-06-22 2010-06-23 2010-06-24 
     299  305  124  129  295  296  278   0 

Чтобы получить длину интервалов с разрядом значения больше нуля:

tapply(flow$discharge, as.Date(flow$Date), function(x) rle(x>0)$lengths[rle(x>0)$values] ) 
#-------- 
$`2010-06-01` 
[1] 138 79 

$`2010-06-02` 
[1] 95 195 239 

$`2010-06-03` 
[1] 57 360 

$`2010-06-04` 
[1] 6 457 

$`2010-06-05` 
integer(0) 

$`2010-06-06` 
integer(0) 

... Snipped output 

Если вы хотите посмотреть на распределение этих длительностей, вам нужно будет отменить этот результат. (И помните, что продолжительность которых были расколоты в полночи, возможно, повлияла подсчеты и длительность.) Если вы просто хотели длительностей без даты, а затем использовать это:

flowrle <- rle(flow$discharge>0) 
flowrle$lengths[!is.na(flowrle$values) & flowrle$values] 
#---------- 
[1] 138 79 95 195 296 360 6 457 263 17 203 79 80 85 30 189 17 270 127 107 31 1 
[23] 2 1 241 311 229 13 82 299 305 3 121 129 295 3 2 291 278 
+0

Привет, Двин, спасибо за ваш ответ. Но, похоже, я не ясно объяснил свою проблему. Сначала нужно проверить ненулевое значение, а затем найти, сколько ненулевых значений существует, прежде чем оно снова достигнет нулевого значения. Результат, который вы показали, имеет ежедневные ненулевые минуты, я думаю. То, что я хочу понять, это длительность выпуска потока. Напр. за один день может быть несколько выпусков, и я хочу отметить, в какое время начался выпуск и как долго он продолжался до того, как он достиг нулевого значения. Надеюсь, это объяснит проблему немного лучше. –

+1

Это достаточно легко обеспечить. Вам просто нужно быть готовым бороться с нерегулярными цифрами в день. –

+0

DWin, большое вам спасибо за ваш обновленный ответ. Мне было интересно, можно ли выводить средние ненулевые значения разряда для вычисленной длины интервала? –

Смежные вопросы