JJchry
JJchry

Reputation: 25

Dynamic statement in dplyr mutate

I have a main dataframe.I need to mutate and create new variables based on various conditions.New variable name and conditions are dynamic. I managed to get the conditions as a column in another dataframe.The problem i need to solve is to evaluate the statements in main dataframe.

eg

x <- runif(10)
#convert to DF
DF <- as.data.frame(x)
DF[1:15] <- sapply(1:15, "+", rnorm(5,60,15))
names(DF) <- paste0("col", 1:15)

-- DF is main dataframe

indx1<-c(1:4)
condition<-c('mutate(AA1=ifelse(col1<.5&col6>.1,1,0))','mutate(CA1=ifelse(col11<.7 & col5>.2,1,0))',
             'mutate(AB1=ifelse(col12<.1 & col8>.2,1,0))','mutate(C1=ifelse(col3<.56 & col7>.2,1,0))')

cond_df=data.frame(indx1,condition)

-- cond_df is the condition DF

  indx1                                  condition
1     1    mutate(AA1=ifelse(col1<.5&col6>.1,1,0))
2     2 mutate(CA1=ifelse(col11<.7 & col5>.2,1,0))
3     3 mutate(AB1=ifelse(col12<.1 & col8>.2,1,0))
4     4  mutate(C1=ifelse(col3<.56 & col7>.2,1,0))

i need to execute each of the condition in main dataframe so that new variables AA1,CA1 -- will be created. Any assistance would be really helpful.

Upvotes: 1

Views: 162

Answers (2)

Paul
Paul

Reputation: 9087

Use eval and parse to create the data frames. Then select the new columns and combine them together.

map(
  condition,
  ~eval(parse(text = paste0("DF %>% ", .)))
) %>%
  map_dfc(~select(., -starts_with("col")))
#>    AA1 CA1 AB1 C1
#> 1    0   0   0  0
#> 2    0   0   0  0
#> 3    0   0   0  0
#> 4    0   0   0  0
#> 5    0   0   0  0
#> 6    0   0   0  0
#> 7    0   0   0  0
#> 8    0   0   0  0
#> 9    0   0   0  0
#> 10   0   0   0  0

Upvotes: 1

Dayne
Dayne

Reputation: 502

The values to be assigned to the new variables seem to be boolean (which you may have chosen to simplify the example). But if it is indeed boolean then this becomes very simple:

DF%>%
  mutate(AA1=as.numeric(col1<.5& col6>.1),
         CA1=as.numeric(col11<.7 & col5>.2),
         AB1=as.numeric(col12<.1 & col8>.2),
         C1=as.numeric(col3<.56 & col7>.2))

Output:

      col1     col2     col3     col4     col5     col6     col7     col8
1 31.91324 33.91324 35.91324 37.91324 39.91324 41.91324 43.91324 45.91324
2 67.98138 69.98138 71.98138 73.98138 75.98138 77.98138 79.98138 81.98138
3 72.32649 74.32649 76.32649 78.32649 80.32649 82.32649 84.32649 86.32649
4 66.96833 68.96833 70.96833 72.96833 74.96833 76.96833 78.96833 80.96833
5 59.78516 61.78516 63.78516 65.78516 67.78516 69.78516 71.78516 73.78516
6 32.91324 34.91324 36.91324 38.91324 40.91324 42.91324 44.91324 31.91324
      col9    col10    col11    col12    col13    col14    col15 AA1 CA1 AB1 C1
1 32.91324 34.91324 36.91324 38.91324 40.91324 42.91324 44.91324   0   0   0  0
2 68.98138 70.98138 72.98138 74.98138 76.98138 78.98138 80.98138   0   0   0  0
3 73.32649 75.32649 77.32649 79.32649 81.32649 83.32649 85.32649   0   0   0  0
4 67.96833 69.96833 71.96833 73.96833 75.96833 77.96833 79.96833   0   0   0  0
5 60.78516 62.78516 64.78516 66.78516 68.78516 70.78516 72.78516   0   0   0  0
6 33.91324 35.91324 37.91324 39.91324 41.91324 43.91324 45.91324   0   0   0  0

Upvotes: 0

Related Questions