Как преобразовать числа в буквы на основе фактического порядка значений?

Я думаю, что это должна быть довольно простая проблема, но я не могу найти ответ. По сути, я хочу добавить префикс к значениям столбца, но без использования условного оператора любого типа. Это возможно?

т. е. я хочу что-то, что дает тот же результат, что и

mtcars %>% 
  mutate(new_cyl = str_c(case_when(cyl == 6 ~ letters[1],
                                   cyl == 4 ~ letters[2],
                                   cyl == 8 ~ letters[3]), ") ", cyl))

Но без использования case_when или любого другого условного предложения.

Мой ожидаемый результат добавит что-то (в данном случае буквы) к значениям столбца в том порядке, в котором они появляются. Здесь это выглядит так:

Как преобразовать числа в буквы на основе фактического порядка значений?

Это не кажется мне ясным. Можете ли вы показать ожидаемый результат? Это просто "добавьте a ко всем 6-цилиндровым автомобилям, b ко всем 4-цилиндровым автомобилям, ..."?

r2evans 21.05.2019 21:05

Вы можете создать таблицу поиска префиксов для каждого значения cyl, объединить и вставить столбцы.

camille 21.05.2019 21:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
149
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если вы хотите присвоить букву всем значениям «cyl»:

mtcars %>%
 mutate(new_cyl = paste0(letters[cyl], ") ", cyl))

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb new_cyl
1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4    f) 6
2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4    f) 6
3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1    d) 4
4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1    f) 6
5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2    h) 8
6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1    f) 6
7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4    h) 8
8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2    d) 4
9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2    d) 4
10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4    f) 6

Чтобы назначить буквы на основе фактического порядка значений «cyl»:

mtcars %>%
 mutate(dup = cumsum(!duplicated(cyl))) %>%
 group_by(cyl) %>%
 mutate(dup = first(dup),
        new_cyl = paste0(letters[dup], ") ", cyl)) %>%
 ungroup() %>%
 select(-dup) 

     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb new_cyl
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>  
 1  21       6 160     110  3.9   2.62  16.5     0     1     4     4 a) 6   
 2  21       6 160     110  3.9   2.88  17.0     0     1     4     4 a) 6   
 3  22.8     4 108      93  3.85  2.32  18.6     1     1     4     1 b) 4   
 4  21.4     6 258     110  3.08  3.22  19.4     1     0     3     1 a) 6   
 5  18.7     8 360     175  3.15  3.44  17.0     0     0     3     2 c) 8   
 6  18.1     6 225     105  2.76  3.46  20.2     1     0     3     1 a) 6   
 7  14.3     8 360     245  3.21  3.57  15.8     0     0     3     4 c) 8   
 8  24.4     4 147.     62  3.69  3.19  20       1     0     4     2 b) 4   
 9  22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2 b) 4   
10  19.2     6 168.    123  3.92  3.44  18.3     1     0     4     4 a) 6

Здесь он, во-первых, создает кумулятивную сумму неповторяющихся значений «cyl». Во-вторых, он группируется по "cyl". Наконец, он берет первое значение кумулятивной суммы неповторяющихся значений и присваивает ему букву.

Это отбрасывается, если значения cyl не появляются в данных в порядке их букв префикса. Если вы расположите данные по cyl перед тем, как вставлять буквы, вы получите 4-a, 6-b, 8-c. Вопрос не дает полной ясности, следует ли назначать буквы по порядку в данных, или есть ли причина, по которой 6 является и т. д.

camille 21.05.2019 21:28

@camille, значения должны быть в том порядке, в котором они указаны в столбце

John-Henry 21.05.2019 21:32

@camille, основываясь на ожидаемом результате, я бы сказал, что OP хочет назначить новую букву, когда появится новое значение «cyl». Если это не так, то может и не работать, вы правы.

tmfmnk 21.05.2019 21:33

Понял, я вижу, что было добавлено к вопросу

camille 21.05.2019 21:35

Вы можете сделать небольшую справочную таблицу префиксов. Таким образом, вы будете знать, что правильно сопоставляете значения cyl с их префиксами, а не зависите от правильности порядка данных. Затем присоединитесь к поиску ваших данных и вставьте.

library(dplyr)

lookup <- data.frame(
  cyl = c(6, 4, 8),
  prefix = letters[1:3]
)

В случае, когда вы хотите создать префиксы на основе порядка столбца cyl, а не жестко кодировать значения cyl для их префиксов, вы можете создать таблицу поиска более динамично, например:

lookup <- data.frame(
  cyl = unique(mtcars$cyl),
  prefix = letters[seq_along(unique(mtcars$cyl))]
)

# select is just to get extra columns out of the way to show here
mtcars %>%
  select(cyl) %>%
  left_join(lookup, by = "cyl") %>%
  mutate(new_cyl = paste(prefix, cyl, sep = ") ")) %>%
  head()
#>   cyl prefix new_cyl
#> 1   6      a    a) 6
#> 2   6      a    a) 6
#> 3   4      b    b) 4
#> 4   6      a    a) 6
#> 5   8      c    c) 8
#> 6   6      a    a) 6

Идеальный ответ. Моей первой мыслью было злоупотребить factor для индексации, но так гораздо понятнее.

Gregor Thomas 21.05.2019 23:25
Ответ принят как подходящий

Вы можете использовать factor() для маркировки:

mtcars %>%
  mutate(
    new_cyl = paste(factor(x, unique(x), letters[seq(unique(x))]), cyl, sep = ') ')
  )

Выход (голова):

#    mpg cyl disp  hp drat    wt  qsec vs am gear carb new_cyl
# 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4    a) 6
# 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4    a) 6
# 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    b) 4
# 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1    a) 6
# 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2    c) 8
# 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1    a) 6

Обобщается как функция:

append_prefix <- function(x, sort = F){
  out <- paste(factor(x, unique(x), letters[seq(unique(x))]), x, sep = ') ')
  if (sort) out <- paste(factor(x, sort(unique(x)), letters[seq(unique(x))]), x, sep = ') ')
  return(out)
}

Другие вопросы по теме