2

I have this data.set

  people <- c("Arthur", "Jean", "Paul", "Fred", "Gary")
  question1 <- c(1, 3, 2, 2, 5)
  question2 <- c(1, 0, 1, 0, 3)
  question3<- c(1, 0, 2, 2, 4)
  question4 <- c(1, 5, 2, 1, 5)

  test <- data.frame(people, question1, question2, question3, question4)

  test

Here is my output :

     people question1 question2 question3 question4
   1 Arthur         1         1         1         1
   2   Jean         3         0         0         5
   3   Paul         2         1         2         2
   4   Fred         2         0         2         1
   5   Gary         5         3         4         5

I want to order the results of each people like this (descending order based on values from left to right columns) in a new data.frame. Ne names of the new columns are letters or anything else.

     people          A        B         C         D
   1 Arthur         1         1         1         1
   2   Jean         5         3         0         0
   3   Paul         2         2         2         1
   4   Fred         2         2         2         0
   5   Gary         5         5         4         3
Wilcar
  • 2,349
  • 2
  • 21
  • 48

3 Answers3

2

With base R apply function sort to the rows in question but be carefull, apply returns the transpose:

test[-1] <- t(apply(test[-1], 1, sort, decreasing = TRUE))

test
#  people question1 question2 question3 question4
#1 Arthur         1         1         1         1
#2   Jean         5         3         0         0
#3   Paul         2         2         2         1
#4   Fred         2         2         1         0
#5   Gary         5         5         4         3
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
1

One dplyr and tidyr option could be:

test %>%
 pivot_longer(-people) %>%
 group_by(people) %>%
 arrange(desc(value), .by_group = TRUE) %>%
 mutate(name = LETTERS[1:n()]) %>%
 pivot_wider(names_from = "name", values_from = "value")

  people     A     B     C     D
  <fct>  <dbl> <dbl> <dbl> <dbl>
1 Arthur     1     1     1     1
2 Fred       2     2     1     0
3 Gary       5     5     4     3
4 Jean       5     3     0     0
5 Paul       2     2     2     1
tmfmnk
  • 38,881
  • 4
  • 47
  • 67
1

Solution using tidyverse (i.e. dplyr and tidyr):

library(tidyverse)
test %>%
  pivot_longer(cols=-people, names_to="variable",values_to = "values") %>% 
  arrange(people, -values) %>% 
  select(people, values) %>% 
  mutate(new_names = rep(letters[1:4], length(unique(test$people)))) %>% 
  pivot_wider(names_from = new_names,
              values_from = values)

This returns:

# A tibble: 5 x 5
  people     a     b     c     d
  <fct>  <dbl> <dbl> <dbl> <dbl>
1 Arthur     1     1     1     1
2 Fred       2     2     1     0
3 Gary       5     5     4     3
4 Jean       5     3     0     0
5 Paul       2     2     2     1

Explanation:

  1. bring data into 'long' form so we can order it on the values of all the 'question' variables.

  2. order (arrange) on people and -values (see above)

  3. remove the not used variable variable

  4. create a new column to hold the new names, name them A-D, for each value of person

  5. bring the data into 'wide' form, creating new columns from the new names

dario
  • 6,415
  • 2
  • 12
  • 26