从两个不同的列满足条件时检索后续行

时间:2019-03-19 05:16:45

标签: r

我有一个数据框架,其数据如下所示:

  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]->属于部件= 123和供应商名称= ABC的所有行均应被排除在外。

零件= 123,供应商名称= XYZ,维修== 1在第四位置。因此,检索第4、5、6和7行。

要考虑的条件是考虑位置> 3和修复== 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 个答案:

答案 0 :(得分:2)

您的格式似乎适合于表示(报告),用于数据处理。在执行诸如删除重复的行以进行可视分组之类的操作之前,确实应该进行任何此类处理。

最终,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 :(得分:1)

使用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