根据高于特定值的每一行从一个数据帧创建多个数据帧

Creating multiple dataframes from one based on every row above a certain value

我目前有一个 excel sheet,这是我公司使用的 class 点差 sheet 的通用格式。行不是固定的,但它们通常看起来像这样

ID  work_order  Item                            value
1               hero                            9399393
2               zero                            393030
3               hereto                          3322
4               Subsidy Transfer 2018 Medium    9292
5   203         akron                           17272
6   002         saffron                         2345
7   004         Percentage Dispersed            2222
8   005         hi                              105
9   203         bye                             202
10  202         END          
11    
12 UNFORMATTED DATA

所以我想把它分成三个不同的数据框。 1. 以 "Subsidy Transfer" 开头的 call_type 之前和包括的每一行 2. "Subsidy Transfer" 之后的每一行以及 "Percentage Dispersed" 之前的所有内容 3. "Percentage Dispersed" 之后和之前的每一行,包括 "END"

所以我的代码肯定会找到我要查找的行...

df[grep("Subsidy Transfer", df$Item), ]

但我不确定如何为三个组复制这个以获得三个对象,同时还保留变量名。从本质上讲,三种情况之上和之下的所有内容如果有意义的话。

最后,我希望看到三个不同的数据框供我使用上述规范进行操作。

您只需要 Item 列进行分组,所以我简化了您的数据框。

library(dplyr)
library(tidyr)
workflow <- data.frame(
    Item = c("a","c","d","Subsidy Transfer 2018 Medium ","a","g","f","d","Percentage Dispersed  ","e","END")
)
> workflow
                            Item
1                              a
2                              c
3                              d
4  Subsidy Transfer 2018 Medium 
5                              a
6                              g
7                              f
8                              d
9         Percentage Dispersed  
10                             e
11                           END

回答你的问题

您需要标记关键行(例如使用标签 1,2,3)并使用 tidyr::fill() 用关键行的标签填充缺失值。

result <- workflow %>%
    mutate(group = case_when(
        grepl("^Subsidy Transfer",Item) ~ 1L,
        grepl("^Percentage Dispersed",Item) ~ 2L,
        grepl("^END",Item) ~ 3L
    )) %>%
    fill(group,.direction = "up") %>%
    group_by(group)

result_list <- group_split(result)
> result_list
[[1]]
# A tibble: 4 x 2
  Item                            group
  <fct>                           <int>
1 a                                   1
2 c                                   1
3 d                                   1
4 "Subsidy Transfer 2018 Medium "     1

[[2]]
# A tibble: 5 x 2
  Item                     group
  <fct>                    <int>
1 a                            2
2 g                            2
3 f                            2
4 d                            2
5 "Percentage Dispersed  "     2

[[3]]
# A tibble: 2 x 2
  Item  group
  <fct> <int>
1 e         3
2 END       3

使用 stringr 包,因为 grep 函数族未向量化。

df$split <- cumsum(stringr::str_detect(df$call_type, "Subsidy Transfer|Percentage|END")) # Identify cutoff rows
df$split <- df$split - stringr::str_detect(df$call_type, "Subsidy Transfer|Percentage|END") # Make cutoff rows belong to the preceding group

split(df, df$split) # split by these groups

这个怎么样?:

您可以创建一个空列表来保存拆分的 3 个数据框:

df_split<-list()

df_split<-list(df[1:which(df$Item=="Subsidy Transfer 2018 Medium"),], 
               df[(1+which(df$Item=="Subsidy Transfer 2018 Medium")):which(df$Item=="Percentage Dispersed"),],
               df[which(df$Item=="Percentage Dispersed") +1:length(df),])