Добавьте столбец во фрейм данных, чтобы отобразить самое последнее описание

#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. ОК. Пожалуйста, ознакомьтесь с моими обновлениями. Теперь это должно сработать!