#r
#r
Вопрос:
df
a = c("aa", "bb", "cc", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb", "cc", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb","bb")
b = c("aa", "bb", "cc", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb", "cc", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb","bb")
c = c("aa", "aa", "aa", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb", "cc", "bb", "bb", "cc","bb", "bb", "cc", "cc", "bb","bb")
d = c(1, 1, 2, 2, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 1, 1, 1, 1, 1)
df = data.frame(a,b,c,d)
Имена столбцов:
cols <- c("a","b","c")
Функция:
rare_label <- function(x){
freq = prop.table(table(unlist(x)))
make_rare = names(freq)[freq < 0.20]
lapply(x,
function(x) {
replace(x, x %in% make_rare, "Rare")
})}
Требуется оценить с помощью dplyr::mutate(across())
доли всех значений, объединенных в a, b, c, а затем изменить любую категорию с долей ниже 20% на «Редкую».
Вывод:
a b c
Rare Rare Rare
bb bb Rare
cc cc Rare
bb bb bb
bb bb bb
cc cc cc
bb bb bb
. . .
. . .
. . .
Использование приведенного ниже кода выдает ошибку, и я не уверен, почему.
df %<>%
mutate(across(where(cols), ~rare_label(.)
Ошибка: неожиданный символ в: » мутировать (поперек(где(cols),
~ rare_label(.) Просмотр»
Комментарии:
1. ваш код в первой строке не работает, один из столбцов короче
2. Исправлено, извините
Ответ №1:
Одним из вариантов может быть:
df %>%
mutate(across(all_of(cols),
~ replace(., . %in% names(which(prop.table(table(.)) < 0.20)), "rare")))
a b c d
1 rare rare rare 1
2 bb bb rare 1
3 cc cc rare 2
4 bb bb bb 2
5 bb bb bb 3
6 cc cc cc 3
7 bb bb bb 1
8 bb bb bb 1
9 cc cc cc 1
10 cc cc cc 1
Если вы хотите применить существующую функцию:
fun <- function(x) replace(x, x %in% names(which(prop.table(table(x)) < 0.20)), "rare")
df %>%
mutate(across(all_of(cols), fun))
Комментарии:
1. Спасибо, но как я могу выполнить это вычисление с помощью функции?
2. Обновил сообщение.
Ответ №2:
Ваш код работает хорошо, просто измените канал и значения следующим образом:
#Code
df %>%
mutate(across(c(a:c), ~rare_label(.))
Вывод:
a b c d
1 Rare Rare Rare 1
2 bb bb Rare 1
3 cc cc Rare 2
4 bb bb bb 2
5 bb bb bb 3
6 cc cc cc 3
7 bb bb bb 1
8 bb bb bb 1
9 cc cc cc 1
10 cc cc cc 1
11 bb bb bb 1
12 cc cc cc 1
13 bb bb bb 2
14 bb bb bb 2
15 cc cc cc 3
16 bb bb bb 3
17 bb bb bb 1
18 cc cc cc 1
19 cc cc cc 1
20 bb bb bb 1
21 bb bb bb 1
Ответ №3:
Ваша функция верна, но вам нужно внести 2 изменения.
- Удалите
lapply
и сохраните последнюю строку как :
replace(x, x %in% make_rare, "Rare")
- Удалить
where
изacross
, поскольку вы вызываете столбец по их именам.
После внесения этих изменений ваш код должен работать.
Другой вариант — использовать forcats
пакет, в котором есть функции для выполнения подобных действий.
library(dplyr)
library(forcats)
df %>%
mutate(across(all_of(cols),fct_lump_min, min = n() * .2, other_level = "rare"))
# a b c d
#1 rare rare rare 1
#2 bb bb rare 1
#3 cc cc rare 2
#4 bb bb bb 2
#5 bb bb bb 3
#6 cc cc cc 3
#7 bb bb bb 1
#8 bb bb bb 1
#9 cc cc cc 1
#10 cc cc cc 1
#11 bb bb bb 1
#12 cc cc cc 1
#13 bb bb bb 2
#...
fct_lump_min
изменяет все факторы на «редкие», которые встречаются менее чем в 20% случаев (0,2 * n()). Здесь мы передаем число для n
снижения уровней, я не смог найти функцию, которая работает путем передачи самой пропорции, fct_lump_prop
делает что-то еще.