Search code examples
rfor-loopappendmin

Append Min values of Block of Rows as a new column


I have the following data

head(datakurz)

Datum Abfluss       days
1 1968-01-01   0.681 1968-01-01
2 1968-01-02   0.610 1968-01-02
3 1968-01-03   0.610 1968-01-03
4 1968-01-04   0.790 1968-01-04
5 1968-01-05   0.904 1968-01-05
6 1968-01-06   3.720 1968-01-06
....
....
....

I want to calculate the min values of each 5 rows , so basically min of (0.681,0.610,0.610,0.790,0.904) = 0.610

this is done by my function

Datum <- datad$days[1:100]
Abfluss <- datad$q[1:100]
datakurz <- data.frame(Datum, Abfluss)

datakurz$days <- as.Date(datakurz$Datum, format="%Y-%m-%d")
class(datakurz$days)

head(datakurz)

# Blöcke gleicher Größe (window size) und deren Minima berechnen

#minimum <- numeric(ws)

zaehler <-  nrow(datakurz) / 5 #Anzahl Zeilen Datensatz durch ws teilen -> Anzahl Blöcke
azeile <- 1
ezeile <- 5

for(i in 1:zaehler){
  minimum <- min(datakurz$Abfluss [azeile:ezeile])
  print(minimum)
  azeile <- azeile+5
  ezeile <- ezeile+5
}

This generates the following output

[1] 0.61 
[1] 0.828
[1] 0.681
[1] 1.41
[1] 0.79
[1] 0.904
[1] 0.828
[1] 0.718
[1] 0.904
[1] 0.79
[1] 0.944
[1] 1.03
[1] 0.866
[1] 1.07
[1] 1.07
[1] 1.25
[1] 0.944
[1] 0.828
[1] 0.79
[1] 1.07

so basically 0.61 is the min of the first 5 values 0.828 is the min value of the next block auf 5 values and so on...

Now I want to append these values as a column to the data frame, but just the min. value of each block of 5 values (the rest should be null)

Desired output

Datum Abfluss       days         min
1 1968-01-01   0.681 1968-01-01  NULL
2 1968-01-02   0.610 1968-01-02  0.610
3 1968-01-03   0.610 1968-01-03  0.610
4 1968-01-04   0.790 1968-01-04  NULL
5 1968-01-05   0.904 1968-01-05  NULL
6 1968-01-06   3.720 1968-01-06  ...


Anyone can help me?


Solution

  • You can use ave to find the min for a group of 5.

    D$min <- ave(D$q, (seq_len(nrow(D))-1) %/% 5, FUN=function(x)
     ifelse(x==min(x), x, NA))
    D
    #    q min
    #1   1   1
    #2   2  NA
    #3   3  NA
    #4   4  NA
    #5   5  NA
    #6   6   6
    #7   7  NA
    #8   8  NA
    #9   9  NA
    #10 10  NA
    #11 11  11
    #12 12  NA
    #13 13  NA
    #14 14  NA
    #15 15  NA
    

    Data:

    D <- data.frame(q=1:15)