#r #dplyr #forcats
#r #dplyr #forcats
Вопрос:
Я пытаюсь автоматически изменить метки столбца factor с помощью кода tidyverse, и у меня возникли проблемы с изменением меток на основе простой функции.
Некоторые примеры данных будут выглядеть следующим образом:
subjectid Parameter value
<chr> <fct> <dbl>
1 13 alpha_IST 0.0751
2 13 alpha_IEX 15.7
3 13 alpha_CB 0.236
4 15 alpha_IST 0.0680
5 15 alpha_IEX 16.5
6 15 alpha_CB 0.282
7 17 alpha_IST 0.0793
(Для воспроизведения вывод из dput для первых 6 строк приведен ниже)
structure(
list(
subjectid = c("13", "13", "13", "15", "15", "15"),
Parameter = structure(c(3L, 2L, 1L, 3L, 2L, 1L), .Label = c("alpha_CB", "alpha_IEX", "alpha_IST"), class = "factor"),
value = c(0.0751, 15.7, 0.236, 0.0680, 16.5, 0.282)
),
row.names = c(NA, -6L),
class = c("tbl_df", "tbl", "data.frame")
)
Я пытаюсь удалить избыточную первую половину меток параметров (т.Е. Удалить alpha_).
Учитывая, что вышеупомянутый объект называется медианами, я могу сделать это с помощью:
par_labels <- sapply(
strsplit(levels(medians$Parameter), "_"),
function(x) {
x[2]
}
)
medians %>% mutate(Parameter = factor(Parameter, labels = par_labels))
Кажется, я должен быть в состоянии создать эту же функциональность, используя функцию fct_relabel , однако, похоже, я не могу заставить ее работать.
medians %>%
mutate(Parameter = fct_relabel(Parameter, function(x) {
strsplit(x, "_")[2]
}))
что выдает ошибку Error: Problem with mutate() input Parameter. ✖ new_levels must be a character vector
.
Я также пытался:
medians %>%
mutate(Parameter = fct_relabel(Parameter, function(x) {
strsplit(x, "_")[[1]][2]
}))
который имеет сообщение об ошибке следующего вида: Error: Problem with mutate() input Parameter. ✖ new_levels must be the same length as levels(f): expected 3 new levels, got 1.
Есть другие комбинации, которые я пробовал с аналогичным отсутствием успеха, и я мог видеть, что преобразование в символьный вектор, использование tidyr для разделения, а затем преобразование обратно в factor будет работать, но я чувствую, что это должно быть возможно способом, аналогичным тому, что я пробовал. Возможно ли это?
Ответ №1:
Вы можете использовать fct_relabel
как :
library(dplyr)
library(forcats)
medians %>%
mutate(Parameter = fct_relabel(Parameter,
function(x) sapply(strsplit(x, "_"), `[`, 2)))
# subjectid Parameter value
# <chr> <fct> <dbl>
#1 13 IST 0.0751
#2 13 IEX 15.7
#3 13 CB 0.236
#4 15 IST 0.068
#5 15 IEX 16.5
#6 15 CB 0.282
Однако для этой проблемы это то, что я бы использовал в base R :
levels(medians$Parameter) <- sub('.*_', '', levels(medians$Parameter))
Или с помощью fct_relabel
:
medians %>%
mutate(Parameter = fct_relabel(Parameter, ~ sub('.*_', '', .x)))