6

i have a rather specific question: how can I make a string into a factor and set its contrasts within a pipe ?

Let's say that I have a tibble like the following

tib <- data_frame (a = rep(c("a","b","c"),3, each = T), val = rnorm(9))

Now, I could use then two separate lines

tib$a <- factor(tib$a)
contrasts(tib$a) <- contr.sum(3)

But what If I wanted to perform the same actions within a pipe from dplyr ?

Federico Nemmi
  • 167
  • 1
  • 8

2 Answers2

7

Everything in R is a function. You just have to know what it's called. In this case, it's contrasts<- to assign contrasts to a factor.

mutate(tib, a=`contrasts<-`(factor(a), , contr.sum(3)))
Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • 1
    Ah! I knew that putting something in `` works to make it a function, but I didn't know this was so extensive. Is it a regular feature ? What I mean is: can I create "pipe friendly version" of any function just following the pattern `name_of_the_function<-` ? And what the empty space between the two commas stand for in your post ? – Federico Nemmi Jul 17 '17 at 11:35
  • 1
    Nearly all the time, yes. – Hong Ooi Jul 17 '17 at 11:37
  • This is so changing my game that I cannot thank you enough. – Federico Nemmi Jul 17 '17 at 11:39
  • Note that this solution may not work on grouped data. – Maxim.K Dec 21 '17 at 15:15
4

Ok, this was a fun puzzle, since I never used do() before, but this works for me:

tib <- data.frame (a = rep(c("a","b","c"),3, each = T), val = rnorm(9)) 

tib = tib %>% mutate(a = factor(a)) %>% do({function(X) {contrasts(X$a) <- contr.sum(3); return(X)}}(.))

contrasts(tib$a)

result:

  [,1] [,2]
a    1    0
b    0    1
c   -1   -1

Hope this helps!

EDIT: Comment request for explanation, see below:

This was also new for me. As I understand it, within the do() call, it says

{func}(.)

this means that a function should be called, with argument ., which is the dataframe in a do call. within func, we then specify the function as

function(X) {operation to perform on X}

so adding this together:

{function(X) {operation to perform on X}}(.)

Which means . is used as argument in function X, so it basically becomes 'operation to perform on .'

Florian
  • 24,425
  • 4
  • 49
  • 80
  • Thanks a lot for your answer. Would you mind tear down a bit the do call for me ? I am not sure why there are two accolades. – Federico Nemmi Jul 17 '17 at 11:19
  • No problem, I liked the puzzle. Would you consider accepting my answer (checkmark below votes)? Thanks! – Florian Jul 17 '17 at 11:21
  • 1
    edited the answer, since you requested for some explanation. Hope this helps! – Florian Jul 17 '17 at 11:25
  • 1
    Yes, now is indeed more clear! And it worked as a charm, so answer accepted! Your example of do use will be certainly of great help to me in the future ! – Federico Nemmi Jul 17 '17 at 11:28