2017-10-21 4 views
1

Je suis nouveau à R donc je m'excuse si c'est une question de base. J'ai un df avec 12k jours de données de hauteur de la rivière. J'ai fait un filtre pour quand la rivière est> 28ft. Mais maintenant je voudrais casser cette df filtrée dans une liste pour quand la rivière est> 28 pi pendant x jours consécutifs. Ainsi par exemple si la rivière est> 28ft pendant 20 jours je voudrais que cela soit groupé ensemble.Comment faire une liste par dates étant dans une rangée dans R?

library(dplyr) 

RawData <- read.csv("c:/Users/Anthony/Desktop/R/CSVRiverData.csv") 

RiverData <- cbind(data.frame(as.Date(RawData$Row.Labels, format = "%m/%d/%Y")), 
        RawData$Average.of.height) 

colnames(RiverData) <- c("Date","RiverHeight") 


Filt_River_Data <- filter(RiverData,RiverData$RiverHeight >28) 

Date_Diff <- data.frame(Filt_River_Data$Date - lag(Filt_River_Data$Date, 1L)) 
+0

Voir '? Rle'. Parfois, il est utile de voler 'data.table :: rleid', par exemple. 'RiverData%>% group_by (jours_above_28 = data.table :: rleid (RiverHeight> 28))%>% filter (RiverHeight> 28, n()> 20)' Notez également que vous ne devez pas utiliser le sous-ensemble '$' verbes dplyr; il suffit de se référer directement à la variable, et il sait regarder dans le cadre de données que vous lui avez transmis. – alistaire

Répondre

1

Voici mon approche de force brute pour obtenir le nombre de jours consécutifs, puis les grouper. Il existe peut-être une solution plus élégante quelque part, mais voici un moyen simple de le faire avec des boucles.

# get some reasonable pseudo data 
library(forecast) 
rd <- rnorm(1010,mean=28,sd=10) 
rd <- forecast::ma(rd,order=10) 
rd <- rd[!(is.na(rd))] 
temp.dd <- seq.Date(as.Date("2000-01-01"),by=1,length.out=length(rd)) 
RiverData <- data.frame(temp.dd,rd) 
colnames(RiverData) <- c('Date','RiverHeight') 

# add vector to df and calculate number of consecutive days 
## assume that you want to calcualte # consecutive days based on raw data, not pre-filtered 
RiverData$numConDays <- rep(NA,nrow(RiverData)) 
count = 0 
h_thresh <- 28 
for (i in 1:nrow(RiverData)) { 
    if (RiverData$RiverHeight[i] >= h_thresh) { 
    count = count + 1 
    } else { 
    count = 0 
    } 
    RiverData$numConDays[i] <- count 
} 

# now you can filter as you wish 
## the first condition of > h_thresh shouldn't be necessary 
RiverDataSubset <- RiverData[(RiverData$RiverHeight > h_thresh & RiverData$numConDays > 20),] 
head(RiverDataSubset) 

# get the grouping for each set 
## assumes daily data 
RiverDataSubset$group <- rep(NA,nrow(RiverDataSubset)) 
gg <- 1 
RiverDataSubset$group[1] <- gg 
for (i in 2:nrow(RiverDataSubset)) { 
    if (as.numeric(difftime(RiverDataSubset$Date[i],RiverDataSubset$Date[i-1])) != 1) { 
    gg <- gg +1 
    } 
    RiverDataSubset$group[i] <- gg 
} 
+0

Cela fonctionne super !! j'apprécie beaucoup. Je vous remercie. – akennedy12345