Получение данных из другого столбца из строки, где соответствует другая переменная

Минимальный рабочий пример:

library(dplyr)
df = data.frame(group_id = c("G1","G1", rep("G2",8)),
                prod_id = c(1,2,5,6,7,8,9,10,11,12),
                prod_type = rep(c("a","a", "b", "c","d"),2),
                start = lubridate::dmy(c("01/01/2001", "02/02/2002",
                                         "05/05/2005","06/06/2006", "07/07/2007", "08/08/2008", "09/09/2009","01/01/2010", "02/02/2011", "03/03/2012" )))%>%
  group_by(group_id) %>%
  mutate(next_acd = if_else(lead(prod_type) %in% c("a","c","d"), lead(prod_id), prod_id[NA])) %>%
  tidyr::fill(next_acd, .direction = "up")

ДФ:

group_id prod_id prod_type start      next_acd
   <chr>      <dbl> <chr>     <date>        <dbl>
 1 G1             1 a         2001-01-01        2
 2 G1             2 a         2002-02-02       NA
 3 G2             5 b         2005-05-05        6
 4 G2             6 c         2006-06-06        7
 5 G2             7 d         2007-07-07        8
 6 G2             8 a         2008-08-08        9
 7 G2             9 a         2009-09-09       11
 8 G2            10 b         2010-01-01       11
 9 G2            11 c         2011-02-02       12
10 G2            12 d         2012-03-03       NA

Где next_acd - следующий prod_id в той группе, которая является prod_type "a", "c" или "d".

Теперь я хочу создать новый столбец fin, который является start датой следующего prod_type "a", "c" или "d". т.е. Я хочу сопоставить next_acd с prod_id и получить соответствующий start.

Я попробовал ответ на другой вопрос Получить данные из переменной z, где переменная x = переменная y

df$fin <- df$start[df$prod_id[df$next_acd]]

ДФ:

 group_id prod_id prod_type start      next_acd fin       
   <chr>      <dbl> <chr>     <date>        <dbl> <date>    
 1 G1             1 a         2001-01-01        2 2002-02-02
 2 G1             2 a         2002-02-02       NA NA        
 3 G2             5 b         2005-05-05        6 2010-01-01
 4 G2             6 c         2006-06-06        7 2011-02-02
 5 G2             7 d         2007-07-07        8 2012-03-03
 6 G2             8 a         2008-08-08        9 NA        
 7 G2             9 a         2009-09-09       11 NA        
 8 G2            10 b         2010-01-01       11 NA        
 9 G2            11 c         2011-02-02       12 NA        
10 G2            12 d         2012-03-03       NA NA 

Я не уверен, что здесь происходит. fin правильно введен только для строки 1.

Вот что должно быть на выходе:

group_id prod_id prod_type start      fin        next_acd
   <chr>      <dbl> <chr>     <date>     <date>        <dbl>
 1 G1             1 a         2001-01-01 2002-02-02        2
 2 G1             2 a         2002-02-02 NA               NA
 3 G2             5 b         2005-05-05 2006-06-06        6
 4 G2             6 c         2006-06-06 2007-07-07        7
 5 G2             7 d         2007-07-07 2008-08-08        8
 6 G2             8 a         2008-08-08 2009-09-09        9
 7 G2             9 a         2009-09-09 2011-02-02       11
 8 G2            10 b         2010-01-01 2011-02-02       11
 9 G2            11 c         2011-02-02 2012-03-03       12
10 G2            12 d         2012-03-03 NA               NA

Возможно stackoverflow.com/questions/1299871/… ?

Martin Gal 06.05.2022 16:35

Я не уверен, что это то, что вы имели в виду, но смотрите мой ответ ниже. Но знаете ли вы, почему попытка в вопросе не работает?

Mark Davies 06.05.2022 17:07

Он использует next_acd в качестве индекса строки внутри группы, например. 6 ищет 6-й ряд группы G2. Вы можете использовать функцию match, как показано ниже.

Carl 06.05.2022 17:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
41
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Основываясь на предложении использовать merge:

df1= df[,c("prod_id","start")]%>%rename(fin = start)
df2= df[,c("group_id", "prod_type","prod_id", "start","next_acd")]

left_join(df2, df1, by= c("next_acd" = "prod_id"))

group_id prod_type prod_id start      next_acd fin       
   <chr>    <chr>       <dbl> <date>        <dbl> <date>    
 1 G1       a               1 2001-01-01        2 2002-02-02
 2 G1       a               2 2002-02-02       NA NA        
 3 G2       b               5 2005-05-05        6 2006-06-06
 4 G2       c               6 2006-06-06        7 2007-07-07
 5 G2       d               7 2007-07-07        8 2008-08-08
 6 G2       a               8 2008-08-08        9 2009-09-09
 7 G2       a               9 2009-09-09       11 2011-02-02
 8 G2       b              10 2010-01-01       11 2011-02-02
 9 G2       c              11 2011-02-02       12 2012-03-03
10 G2       d              12 2012-03-03       NA NA     
Ответ принят как подходящий

Аккуратный вариант:

library(tidyverse)

df <- data.frame(
  group_id = c("G1", "G1", rep("G2", 8)),
  prod_id = c(1, 2, 5, 6, 7, 8, 9, 10, 11, 12),
  prod_type = rep(c("a", "a", "b", "c", "d"), 2),
  start = lubridate::dmy(c(
    "01/01/2001", "02/02/2002",
    "05/05/2005", "06/06/2006", "07/07/2007", "08/08/2008", "09/09/2009", "01/01/2010", "02/02/2011", "03/03/2012"
  ))
) %>%
  group_by(group_id) %>%
  mutate(next_acd = if_else(lead(prod_type) %in% c("a", "c", "d"), lead(prod_id), prod_id[NA])) %>%
  fill(next_acd, .direction = "up")

df %>%
  group_by(group_id) %>%
  mutate(fin = start[match(next_acd, prod_id, nomatch = NA_real_)])
#> # A tibble: 10 × 6
#> # Groups:   group_id [2]
#>    group_id prod_id prod_type start      next_acd fin       
#>    <chr>      <dbl> <chr>     <date>        <dbl> <date>    
#>  1 G1             1 a         2001-01-01        2 2002-02-02
#>  2 G1             2 a         2002-02-02       NA NA        
#>  3 G2             5 b         2005-05-05        6 2006-06-06
#>  4 G2             6 c         2006-06-06        7 2007-07-07
#>  5 G2             7 d         2007-07-07        8 2008-08-08
#>  6 G2             8 a         2008-08-08        9 2009-09-09
#>  7 G2             9 a         2009-09-09       11 2011-02-02
#>  8 G2            10 b         2010-01-01       11 2011-02-02
#>  9 G2            11 c         2011-02-02       12 2012-03-03
#> 10 G2            12 d         2012-03-03       NA NA

Created on 2022-05-06 by the reprex package (v2.0.1)

Другие вопросы по теме