Claudio
Claudio

Reputation: 1550

Behavior of R pipe operator after transformation

I am struggling to understand the behavior of the pipe operator (|> in base R, but I have the same problem with magrittr's %>%) when I apply a transformation in one of the steps:

table(iris$Species) |> prop.table() |> round(1)

    setosa versicolor  virginica 
       0.3        0.3        0.3 



table(iris$Species) |> prop.table()*100 |> round(1)

    setosa versicolor  virginica 
  33.33333   33.33333   33.33333  

Why the second command does not pass the result to round?

Upvotes: 3

Views: 174

Answers (3)

akrun
akrun

Reputation: 887951

Another option is to convert to data.frame and use transform

table(iris$Species) |> 
     prop.table() |> 
     as.data.frame() |>
     transform(Freq = round(Freq * 100, 1))

-ouptut

        Var1 Freq
1     setosa 33.3
2 versicolor 33.3
3  virginica 33.3

Upvotes: 1

Anoushiravan R
Anoushiravan R

Reputation: 21938

This can only be a second alternative to the very good solutions provided by dear @ktiu which also contains some interesting new features. We can use multiply_by function from magrittr package, which works with native pipe as well as magrittr pipe:

library(magrittr)

table(iris$Species) |> prop.table() |> multiply_by(100) |> round(digits = 1)

    setosa versicolor  virginica 
      33.3       33.3       33.3 

Upvotes: 4

ktiu
ktiu

Reputation: 2636

In your example, it is only the 100 that is passed to round() -- so it doesn't affect anything since 100 is already a whole number. The same thing happens with %>%.

With magrittr's pipe, we can fix this by calling * as a function explicitly with backticks:

table(iris$Species) %>% prop.table() %>% `*`(100) %>% round(1)

Within base R, AFAIK we have to include an anonymous function to multiply:

table(iris$Species) |> prop.table() |> (\(x) x * 100)() |> round(1)

(But see Anoushiravan R's answer for a workaround.)

Upvotes: 3

Related Questions