1

I have a data frame with x columns. From each column, I want to create a new column, where data are replaced by their ranks, but the ranks are not standard but follow a pyramid style.

To do this, I am tryng to use mutate within a function and loop that function over the different columns.

I have tried this in different ways. However, I keep on getting an error (see below code) and I do not understand why I get that error.

df <- tibble(Z1 = rnorm(40), Z2 = rnorm(40))
pyramid = c(rep(5,2),rep(4,3),rep(3,3), rep(2,4), rep(1,5), rep(0,6), 
                    rep(-1, 5), rep(-2,4), rep(-3, 3), rep(-4,3), rep(-5,2))


for (i in 1:2){
  Z <- rlang::sym(paste("Z", i, sep=""))
  QS <- rlang::sym(paste("QS", i, sep=""))
  
  df <- df %>% arrange(!!-Z) %>% mutate(!!QS = pyramid)
}

The error:

Error: unexpected '=' in:
"  
  df <- df %>% arrange(!!-Z) %>% mutate(!!QS ="
> }
Error: unexpected '}' in "}"

Since the following code is working, I suspect it comes from the way I use a symbol to create a new variable. I have also tried using a String and got the same error. I have also tried the double curly instead of the double !! and it got the same issue So I am lost!

for (i in 1:2){
  Z <- rlang::sym(paste("Z", i, sep=""))

  df <- df %>% arrange(!!-Z) %>% mutate(QS2 = pyramid)
}

The expected output should look like this:

# A tibble: 40 x 4
       Z1    Z2   QS1   QS2
    <dbl> <dbl> <dbl> <dbl>
 1 -0.591 1.64     -2     5
 2 -0.132 1.59      0     5
 3 -0.418 1.59     -2     4
 4  1.11  1.52      4     4
 5  1.65  1.15      4     4
 6  0.289 1.11      1     3
 7  1.85  1.09      5     3
 8  0.526 1.07      1     3
 9 -0.436 1.04     -2     2
10 -0.671 0.794    -3     2
# ... with 30 more rows
4
  • What is your expected output? What is pyramid used for? Commented Jun 28, 2020 at 6:56
  • Sorry, I should have done so. I am editing the question to show the expected results; In short I am transforming each value into an index. This index is not linear, because you will have two 5, three 4, etc... This is because I am analysing the results of ranking made by respondents that were made this way (Q-methodologyà Commented Jun 28, 2020 at 7:03
  • 1
    If you use unquoting on the LHS of an assignment you have to replace ´=` by :=, i.e. mutate(!!QS := pyramid). Commented Jun 28, 2020 at 7:28
  • Thank you stefan for this. I had overlooked that Commented Jun 28, 2020 at 7:30

2 Answers 2

1

You can use order in mutate :

library(dplyr)
df %>% mutate(across(everything(), list(QS = ~pyramid[order(.)])))
#In old dplyr
#df %>% mutate_all(list(QS = ~pyramid[order(.)]))

Or in base R :

df[paste0('QS', seq_along(df))] <- lapply(df, function(x) pyramid[order(x)])
Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, much more compact !
1

An option with data.table

library(data.table)
setDT(df)[, paste0('QS', names(df)) := lapply(.SD, function(x) pyramid[order(x)])]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.