Search code examples
rvariable-assignmentmagrittr

Conditional Assignment frame$col <- val with magrittr


What is the Magrittr syntax to assign Iris$column based on Iris$Petal.Length ? Example without Magrittr:

df      <- iris[47:56,]
df$val1 <- NA                                           ## create column
df$val1[which(df$Petal.Length < 1.52)]                         <- "cake"
df$val1[which(df$Petal.Length > 1.55 & df$Petal.Length <=4.55)] <- "pie"
df$val1[which(df$Petal.Length > 4.55)]                        <- "apple"

head(df)

This results in:

Petal.Length Petal.Width  Species    val1

1.6                0.2     setosa     pie

1.4                0.2     setosa     cake

1.5                0.2     setosa     cake

1.4                0.2     setosa     cake

1.4                1.4.  versicolor   apple

Solution

  • The exact equivalent magrittr syntax to what you wrote is :

    df %>% transform(val1 = NA) %$%
      inset(.,Petal.Length < 1.52,"val1","cake") %$%
      inset(.,Petal.Length > 1.55 & Petal.Length <= 4.55,"val1","pie") %$%
      inset(.,Petal.Length > 4.55,"val1","apple")
    

    Or to be really zealous with magrittr's aliases:

    df %>% transform(val1 = NA) %$%
      inset(.,Petal.Length %>% is_less_than(1.52),"val1","cake") %$%
      inset(.,Petal.Length %>% is_greater_than(1.55) & Petal.Length %>% 
      is_weakly_less_than(4.55),"val1","pie") %$%
      inset(.,Petal.Length %>% is_greater_than(4.55),"val1","apple")
    

    And a variant:

    df %>% transform(val1 = NA) %$%
      inset(.,Petal.Length %>% is_less_than(1.52),"val1","cake") %$%
      inset(.,Petal.Length %>% {is_greater_than(.,1.55) & is_weakly_less_than(.,4.55)},"val1","pie") %$%
      inset(.,Petal.Length %>% is_greater_than(4.55),"val1","apple")
    

    The two first are strictly equivalent to this in base (except for the pipes!):

    df %>% transform(val1 = NA) %$%
      `[<-`(.,Petal.Length < 1.52,"val1","cake") %$%
      `[<-`(.,Petal.Length > 1.55 & Petal.Length <= 4.55,"val1","pie") %$%
      `[<-`(.,Petal.Length > 4.55,"val1","apple")
    

    The variant is equivalent to this:

    df %>% transform(val1 = NA) %$%
      `[<-`(.,Petal.Length < 1.52,"val1","cake") %$%
      `[<-`(.,Petal.Length %>% {`>`(.,1.55) & `<=`(.,4.55)},"val1","pie") %$%
      `[<-`(.,Petal.Length > 4.55,"val1","apple")
    

    I used transform because it's a base function while mutate is a dplyr function but they work the same way here.

    For a definition of all the aliases see: ?extract