Получить последующие строки при выполнении условия из двух разных столбцов - PullRequest
0 голосов
/ 19 марта 2019

У меня есть фрейм данных с данными, которые выглядят так:

  Part Number Vendor Name Position Repair
          123         ABC        1      2
           NA        <NA>        2      4
           NA        <NA>        3      1
           NA        <NA>        4      5
           NA        <NA>        5      6
           NA        <NA>        6      3
          123         XYZ        1      4
           NA        <NA>        2      5
           NA        <NA>        3      7
           NA        <NA>        4      1
           NA        <NA>        5      2
           NA        <NA>        6      3
           NA        <NA>        7      6

У меня сгруппированы номер детали и название поставщика. Всякий раз, когда позиционирует столбец> 3 и восстанавливает == 1, извлекает последующие строки.

Предположим, что в данном примере для номера детали = 123 и имени поставщика = ABC, ремонт == 1 находится на третьей позиции [position = 3] -> Все строки, которые принадлежат part = 123, и имя поставщика = ABC должны быть исключенным.

Part = 123 и имя поставщика = XYZ, ремонт == 1 находится на четвертой позиции. Получите 4-й, 5-й, 6-й и 7-й ряды.

Условие, которое следует учитывать, это рассмотреть строки, где Position> 3 и Repair == 1, извлечь все последующие строки

Пример данных:

Input <- structure(list(`Part Number` = c(123, NA, NA, NA, NA, NA, 123, 
NA, NA, NA, NA, NA, NA), `Vendor Name` = c("ABC", NA, NA, NA, 
NA, NA, "XYZ", NA, NA, NA, NA, NA, NA), Position = c(1, 2, 3, 
4, 5, 6, 1, 2, 3, 4, 5, 6, 7), Repair = c(2, 4, 1, 5, 6, 3, 4, 
5, 7, 1, 2, 3, 6)), .Names = c("Part Number", "Vendor Name", "Position", 
"Repair"), row.names = c(NA, -13L), class = c("tbl_df", "tbl", 
"data.frame"))

Я попробовал следующее, но это не привело к тому, что я хотел:

output_table <- Input %>% group_by(`Part Number`,`Vendor Name`) %>% 
mutate(rn=row_number()) %>% filter(rn>=which(pivot$Repair==1)) #Here I'm able to filter subsequent rows where repair==1 but how to exclude the rows which doesn't fall under the mentioned conditions.

output_table <- Input[Input$Position >3 & Input$Repair==1,] # gives me rows matching the condition but I need subsequent rows once the condition is met

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Ваш формат, кажется, ориентирован на презентацию (отчеты), тиски для обработки данных. Любая обработка, подобная этой, действительно должна выполняться перед тем, как вы удалите повторяющиеся строки для визуальной группировки.

В конечном счете, единственная часть, которая вам нужна здесь в group_by, это использование cumany. Остальная часть мутантного кода предназначена для размещения полей NA.

Input %>%
  # assuming order is "safe to assume"
  mutate_at(vars(`Part Number`, `Vendor Name`), zoo::na.locf) %>%
  group_by(`Part Number`,`Vendor Name`) %>%
  filter(cumany(Position > 3 & Repair == 1)) %>%
  # return the first two columns to NA
  mutate(toprow = row_number() == 1L) %>%
  ungroup() %>%
  mutate_at(vars(`Part Number`, `Vendor Name`), ~ if_else(toprow, ., .[NA])) %>%
  select(-toprow)
# # A tibble: 4 x 4
#   `Part Number` `Vendor Name` Position Repair
#           <dbl> <chr>            <dbl>  <dbl>
# 1           123 XYZ                  4      1
# 2            NA <NA>                 5      2
# 3            NA <NA>                 6      3
# 4            NA <NA>                 7      6

Если вы делаете больше обработки данных, я бы посоветовал вам не отменять «перетаскивание меток вниз», а просто делать:

Input %>%
  # assuming order is "safe to assume"
  mutate_at(vars(`Part Number`, `Vendor Name`), zoo::na.locf) %>%
  group_by(`Part Number`,`Vendor Name`) %>%
  filter(cumany(Position > 3 & Repair == 1)) %>%
  ungroup()
# # A tibble: 4 x 4
#   `Part Number` `Vendor Name` Position Repair
#           <dbl> <chr>            <dbl>  <dbl>
# 1           123 XYZ                  4      1
# 2           123 XYZ                  5      2
# 3           123 XYZ                  6      3
# 4           123 XYZ                  7      6
1 голос
/ 19 марта 2019

С помощью dplyr и tidyr вы можете сделать это следующим образом:

library(dplyr)
library(tidyr)
Input %>% 
  fill(`Part Number`, `Vendor Name`) %>%   # fill down missing values
  group_by(`Part Number`, `Vendor Name`) %>%   # group by `Part Number` & `Vendor Name`
  filter( cumsum(Position>3 & Repair==1) >= 1)   # select only rows where the cumulative sum of true/false condition >= 1

Вывод для этого должен быть тем, что вы ищете:

# A tibble: 4 x 4
  `Part Number` `Vendor Name` Position Repair
          <dbl> <chr>            <dbl>  <dbl>
1           123 XYZ                  4      1
2           123 XYZ                  5      2
3           123 XYZ                  6      3
4           123 XYZ                  7      6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...