#r #dplyr
Вопрос:
Я потратил сегодня много часов, чтобы найти решение этой проблемы, там есть похожие темы, но не совсем то, что мне нужно.
Набор данных:
Year <- c(2019, 2020, 2021, 2019, 2020, 2020, 2021, 2021)
Term <- c("2019_T1", "2020_T1", "2021_T1", "2019_T1", "2020_T1", "2020_T2", "2021_T1", "2021_T2")
Code <- c(1,1,1,2,2,2,2,2)
Description <- c("Desc1","Desc1","Desc1", "Desc2", "Desc2", "Desc2", "Desc2_NotRecent","Desc2_Recent")
В результате получится следующая таблица:
Year Term Code Description
1 2019 2019_T1 1 Desc1
2 2020 2020_T1 1 Desc1
3 2021 2021_T1 1 Desc1
4 2019 2019_T1 2 Desc2
5 2020 2020_T1 2 Desc2
6 2020 2020_T2 2 Desc2
7 2021 2021_T1 2 Desc2_NotRecent
8 2021 2021_T2 2 Desc2_Recent
Вопрос:
Как добавить столбец, чтобы отобразить самое последнее описание для каждого кода.
Мне нужно будет найти самые последние, основанные на термине. Возможно, этого можно достичь сначала простым способом, извините, я этого не понял.
Его важное значение-это самое последнее значение в терминах. Здесь самый последний термин-2021_T2. Если выбрано первое значение, это может быть старое описание и запутать заинтересованных лиц.
Результат, который мне нужен:
Year Term Code Description Most_Recent
1 2019 2019_T1 1 Desc1 Desc1
2 2020 2020_T1 1 Desc1 Desc1
3 2021 2021_T1 1 Desc1 Desc1
4 2019 2019_T1 2 Desc2 Desc2_Recent
5 2020 2020_T1 2 Desc2 Desc2_Recent
6 2020 2020_T2 2 Desc2 Desc2_Recent
7 2021 2021_T1 2 Desc2_NotRecent Desc2_Recent
8 2021 2021_T2 2 Desc2_Recent Desc2_Recent
Действительно благодарен за всю помощь. Отредактировано, чтобы включить простое решение от Робина Гертенбаха.
df %>%
group_by(Code) %>%
dplyr:: mutate(Most_Recent = dplyr::last(Description, Term))
Комментарии:
1. совет: вам не нужно
cbind
этого делать, когда вы используетеdata.frame
— сначала он принудит вас к матрице и, возможно, изменит тип ваших столбцов, если вы это заметите.
Ответ №1:
Более короткое решение, никаких соединений или условий
df %>%
group_by(Code) %>%
mutate(Most_Recent = last(Description, Term))
Комментарии:
1. Я получаю ошибку, пытаясь запустить это: Ошибка в проверке(n, dx
2. Это в том наборе данных, который вы предоставили, или в другом? Все это функции dplyr, и я получаю ожидаемый результат.
3. Спасибо, да, это тот же самый. Странно! Я очистил среду, запустил ее снова и получил ту же ошибку.
4. Возможно, у вас конфликт с пространством имен, откуда вы пришли
last
? например?last
, дает ли вамdplyr::last
документацию?5. У меня это есть как в data.table, так и в dplyr, поэтому я вызвал dplyr:: mutate(Most_Recent = последний(Описание, термин)), у меня все еще есть эта ошибка: недопустимый ‘n’ — должен иметь длину один, когда dim(x) равен НУЛЮ, получил 3
Ответ №2:
library(tidyverse)
Year <- c(2019, 2020, 2021, 2019, 2020, 2020, 2021)
Term <- c("2019_T1", "2020_T1", "2021_T1", "2019_T1", "2020_T1", "2020_T2", "2021_T2")
Code <- c(1, 1, 1, 2, 2, 2, 2)
Description <- c("Desc1", "Desc1", "Desc1", "Desc2", "Desc2", "Desc2", "Desc2_Recent")
df <- data.frame(cbind(Year, Term, Code, Description))
df <- df %>%
mutate(Year = Year %>% as.integer())
most_recent_descriptions <-
df %>%
group_by(Code) %>%
arrange(-Year) %>%
slice(1) %>%
transmute(
Code,
Most_Recent = Description
)
df %>%
left_join(most_recent_descriptions)
#> Joining, by = "Code"
#> Year Term Code Description Most_Recent
#> 1 2019 2019_T1 1 Desc1 Desc1
#> 2 2020 2020_T1 1 Desc1 Desc1
#> 3 2021 2021_T1 1 Desc1 Desc1
#> 4 2019 2019_T1 2 Desc2 Desc2_Recent
#> 5 2020 2020_T1 2 Desc2 Desc2_Recent
#> 6 2020 2020_T2 2 Desc2 Desc2_Recent
#> 7 2021 2021_T2 2 Desc2_Recent Desc2_Recent
Создано 2021-09-13 пакетом reprex (v2.0.1)
Комментарии:
1. Большое спасибо, я просто отредактировал, чтобы добавить обновление различных описаний по срокам, я попробую решения по годам.
2. Мои данные могут иметь два описания в заданном термине, есть ли способ отсортировать их по термину?
3. Представьте, что у вас есть описание не только за год, но и за месяц. Затем вы можете сделать
arrange(-Year, -Month)
, чтобы получить описание с самым высоким месяцем этого года.4. Спасибо @danloo, я, похоже, не сделал этого правильно, используя упорядочение каналов(-Год,- Срок) % Я получаю ошибку: Ошибка в сроке : недопустимый аргумент для унарного оператора. Так что, похоже, для этого нужна дата, чтобы это сработало.
5. Снимите
-
сTerm
. По умолчанию расположение выполняется восходящим. Отрицание приводит к поиску по убыванию. Это работает только для чисел. Но вы можете сделать что-то вродеarrange(desc(Term))
Ответ №3:
Разделите Term
значение на два столбца как 'Year'
и 'Term'
, arrange
данные по Year
и Term
и для каждого Code
получите last
значение.
library(dplyr)
library(tidyr)
df %>%
separate(Term, c('Year', 'Term'), sep = '_', convert = TRUE) %>%
arrange(Code, Year, order(gtools::mixedorder(Term))) %>%
group_by(Code) %>%
mutate(Most_Recent = last(Description)) %>%
ungroup
# Code Year Term Description Most_Recent
# <dbl> <int> <chr> <chr> <chr>
#1 1 2019 T1 Desc1 Desc1
#2 1 2020 T1 Desc1 Desc1
#3 1 2021 T1 Desc1 Desc1
#4 2 2019 T1 Desc2 Desc2_Recent
#5 2 2020 T1 Desc2 Desc2_Recent
#6 2 2020 T2 Desc2 Desc2_Recent
#7 2 2021 T1 Desc2_NotRecent Desc2_Recent
#8 2 2021 T2 Desc2_Recent Desc2_Recent
Если вам Year
снова нужны значения Term
и в одном столбце, вы можете добавить unite
их для выполнения описанной выше цепочки.
...ungroup %>% unite(Term, Year, Term)
Комментарии:
1. Большое тебе спасибо, Ронак.
Ответ №4:
Обновление после уточнения: См. Комментарии:
library(tidyverse)
df %>%
group_by(Code) %>%
separate(Term, c("Year", "T"), sep = "_", remove = FALSE) %>%
mutate(T = parse_number(T),
Most_recent = ifelse(Year == max(Year) amp; T == max(T), Description, NA)
) %>%
fill(Most_recent, .direction = "up")
выход:
Term Code Year T Description Most_recent
<chr> <chr> <chr> <dbl> <chr> <chr>
1 2019_T1 1 2019 1 Desc1 Desc1
2 2020_T1 1 2020 1 Desc1 Desc1
3 2021_T1 1 2021 1 Desc1 Desc1
4 2019_T1 2 2019 1 Desc2 Desc2_Recent
5 2020_T1 2 2020 1 Desc2 Desc2_Recent
6 2020_T2 2 2020 2 Desc2 Desc2_Recent
7 2021_T1 2 2021 1 Desc2_NotRecent Desc2_Recent
8 2021_T2 2 2021 2 Desc2_Recent Desc2_Recent
Первый ответ:
Вот tidyverse
как вы могли бы получить свой результат:
library(dplyr)
library(tidyr)
df %>%
group_by(Code) %>%
mutate(Year = as.numeric(Year),
Most_recent = ifelse(Year == max(Year), Description, NA)
) %>%
fill(Most_recent, .direction = "up")
выход:
Year Term Code Description Most_recent
<dbl> <chr> <chr> <chr> <chr>
1 2019 2019_T1 1 Desc1 Desc1
2 2020 2020_T1 1 Desc1 Desc1
3 2021 2021_T1 1 Desc1 Desc1
4 2019 2019_T1 2 Desc2 Desc2_Recent
5 2020 2020_T1 2 Desc2 Desc2_Recent
6 2020 2020_T2 2 Desc2 Desc2_Recent
7 2021 2021_T2 2 Desc2_Recent Desc2_Recent
Комментарии:
1. Это здорово, если описания все одинаковы в течение года, но если в течение года есть два описания в двух терминах, это не работает.
2. ОК. Пожалуйста, ознакомьтесь с моими обновлениями. Теперь это должно сработать!