dre
dre

Reputation: 504

r: coding dummy variables based-on max value for each month

I want to code a new variable called df$dummy based-on the max value in df$var1 for each df$month, where the value will be 1 for the max value and 0 for every other value. See reproducible data set:

df<- data.frame(date= seq.Date(from = as.Date('2017-01-01'), by= 7, 
                length.out = 20), var1= rnorm(20, 5, 3))

df$month<- as.numeric(strftime(df$date, "%m"))

I'm having trouble conceptualizing the conditions for the function. In Excel I would just use the maxif function and specific my criteria. My attempt below does not work:

df$dummy<- apply(df$var1, MARGIN = 2, 
                 function(x) if_else(max(x) %in% df$month, 1, 0))

It returns this error:

Error in apply(df$var1, MARGIN = 2, function(x) if_else(max(x) %in% df$month,  : 
dim(X) must have a positive length

How do I code this dummy variable? Is there a viable dplyr solution using mutate_if?

Upvotes: 0

Views: 224

Answers (2)

DJJ
DJJ

Reputation: 2539

with data.table package it is fairly easy to do it.

library(data.table)

df<- data.frame(date= seq.Date(from = as.Date('2017-01-01'), by= 7, 
                 length.out = 20), var1= rnorm(20, 5, 3))

df$month<- as.numeric(strftime(df$date, "%m"))

set.DT(df)
df[,dummy:=ifelse(max(var1)==var1,1,0),month]

## df
##           date      var1 month dummy
##  1: 2017-01-01  2.213981     1     0
##  2: 2017-01-08  1.768855     1     0
##  3: 2017-01-15  4.765936     1     0
##  4: 2017-01-22  3.930655     1     0
##  5: 2017-01-29  6.548077     1     1
##  6: 2017-02-05 -1.489263     2     0
##  7: 2017-02-12  4.448080     2     0
##  8: 2017-02-19  9.734254     2     1
##  9: 2017-02-26  3.322127     2     0
## 10: 2017-03-05  8.023423     3     1
## 11: 2017-03-12  6.915339     3     0
## 12: 2017-03-19  3.563988     3     0
## 13: 2017-03-26  4.393971     3     0
## 14: 2017-04-02  8.361803     4     0
## 15: 2017-04-09  3.636038     4     0
## 16: 2017-04-16  3.804143     4     0
## 17: 2017-04-23 11.269707     4     1
## 18: 2017-04-30  7.024666     4     0
## 19: 2017-05-07 10.771904     5     1
## 20: 2017-05-14  4.877943     5     0

Upvotes: 1

Frank
Frank

Reputation: 2416

In dplyr, the key is to use group_by to separate the data frame by month. Then, var1 == max(var1) will operate within each month, as you want. For example:

library(dplyr)
df<- data.frame(date= seq.Date(from = as.Date('2017-01-01'), by= 7, length.out = 20), var1= rnorm(20, 5, 3))
df$month<- as.numeric(strftime(df$date, "%m"))

df <- df %>%
  group_by(month) %>%
  mutate(dummy = as.integer(var1 == max(var1))) %>%
  ungroup

Upvotes: 1

Related Questions