У меня есть предопределенный список, содержащий список элементов, как показано ниже:
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? Или есть ли короткий и ясный способ сделать это? Все идеи приветствуются.
Вы можете использовать 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
для каждого случая, если групп более двух.
# 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)
.
Если групп потенциально много, таблица поиска может быть хорошим способом поддерживать:
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
Множество способов снять шкуру с этой конкретной кошки, но например.
df$df_new_rate <- ifelse(df$item %in% group_1, df$item_price * 0.1, df$item_price * 0.2)