Изменить/создать столбец на основе групп, определенных извне

У меня есть предопределенный список, содержащий список элементов, как показано ниже:

group_1<-c("A","B","C")
group_2<-c("D","E","F")

item<-c("A","B","C","D","E","F")
item_price<-(1:6)

df<-data.frame(item,item_price)

> df
  item item_price
1    A          1
2    B          2
3    C          3
4    D          4
5    E          5
6    F          6

И теперь я хотел бы создать новый столбец, умножив item_price на произвольное число, в этом случае для товаров в group_1 item_price будет умножен на 0,1 и 0,2 для товаров в группе 2. Желаемый результат, как показано ниже. :

> df
  item item_price df_new_rate
1    A          1         0.1
2    B          2         0.2
3    C          3         0.3
4    D          4         0.8
5    E          5         1.0
6    F          6         1.2

Поскольку мне нужно будет просмотреть столбец элемента и посмотреть, к какой группе принадлежит тот или иной элемент, нужно ли мне писать здесь цикл for? Или есть ли короткий и ясный способ сделать это? Все идеи приветствуются.

Множество способов снять шкуру с этой конкретной кошки, но например. df$df_new_rate <- ifelse(df$item %in% group_1, df$item_price * 0.1, df$item_price * 0.2)

Axeman 25.06.2024 20:48
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
59
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете использовать ifelse или case_when, если у вас более двух групп:

library(dplyr)

df %>% 
  mutate(df_new_rate = case_when(item %in% group_1 ~ 0.1,
                                 item %in% group_2 ~ 0.2,
                                 .default = 0) * item_price)
#>   item item_price df_new_rate
#> 1    A          1         0.1
#> 2    B          2         0.2
#> 3    C          3         0.3
#> 4    D          4         0.8
#> 5    E          5         1.0
#> 6    F          6         1.2

Вы также можете использовать case_match(): case_match(item, group_1 ~ 0.1, group_2 ~ 0.2, .default = 0), чтобы ОП не приходилось выписывать item для каждого случая, если групп более двух.

LMc 25.06.2024 21:42
# tidyverse solution
library(dplyr)
df <- df |> mutate(
  new_rate = ifelse(item %in% group_1, item_price*.1, item_price*.2)
  )
df

# same, but in base R
df$new_rate <- ifelse(df$item %in% group_1, df$item_price*.1, df$item_price*.2)
df

Поскольку оба значения умножены на item_price, я думаю, будет немного проще использовать item_price * ifelse(item %in% group_1, .1, .2) или df$item_price * ifelse(df$item %in% group_1, .1, .2).

Jon Spring 25.06.2024 21:09

Если групп потенциально много, таблица поиска может быть хорошим способом поддерживать:

library(dplyr)
lookup <- data.frame(item = c(group_1, group_2),
                     rt = c(rep(0.1, length(group_1)),
                            rep(0.2, length(group_2))))

df |> left_join(lookup) |> mutate(df_new_rate = item_price * rt)

Результат

Joining with `by = join_by(item)`
  item item_price  rt df_new_rate
1    A          1 0.1         0.1
2    B          2 0.1         0.2
3    C          3 0.1         0.3
4    D          4 0.2         0.8
5    E          5 0.2         1.0
6    F          6 0.2         1.2

Использование поиска с именем вектор:

lookup <- c(setNames(rep(0.1, length(group_1)), group_1),
            setNames(rep(0.2, length(group_2)), group_2))

df$df_new_rate <- df$item_price * lookup[ df$item ]
#   item item_price df_new_rate
# 1    A          1         0.1
# 2    B          2         0.2
# 3    C          3         0.3
# 4    D          4         0.8
# 5    E          5         1.0
# 6    F          6         1.2

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

Как сортировать пары столбцов в R, сохраняя связанные значения вместе
Вложен ifelse в R с предупреждением «условие имеет длину > 1»
Есть ли лучший способ создать мой фрейм данных?
Как исправить столбец с числовыми значениями, который воспринимается как строковое поле из-за пустых строк в фрейме данных Pandas?
Добавьте значения двух Dataframe на основе похожих значений строк
Обмен датой начала, датой окончания и другими столбцами с более ранней строкой, если даты больше 8 в фрейме данных pandas
Почему сбор LazyFrame перед объединением в Polars решает мою проблему с несоответствиями индексов?
Python: только 2 уникальных имени столбца в фрейме данных, всего 3105 столбцов. Как получить среднее значение строки, сгруппированной по уникальному имени столбца
Как я могу сравнить значение в одном столбце со всеми значениями, которые находятся ДО него в другом столбце, чтобы найти количество уникальных значений, которые меньше?
Присоединиться к фрейму данных с двойной записью