根据高于特定值的每一行从一个数据帧创建多个数据帧
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),])
我目前有一个 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),])