基于列中的字符和数据框中出现的顺序的每个组的子集行

问题描述:

我有一个类似于此的数据。基于列中的字符和数据框中出现的顺序的每个组的子集行

B <- data.frame(State = c(rep("Arizona", 8), rep("California", 8), rep("Texas", 8)), 
    Account = rep(c("Balance", "Balance", "In the Bimester", "In the Bimester", "Expenses", 
    "Expenses", "In the Bimester", "In the Bimester"), 3), Value = runif(24)) 

可以看到,Account有4次出现的元件"In the Bimester"的,两个“块”的两个元件对于每个状态,"Expenses"在它们之间的

这里的顺序很重要,因为第一个块与第二个块没有引用相同的东西。

我的数据实际上比较复杂,它有第四个变量,表示Account的每一行的含义。每个Account元素的元素数量(因子本身)可以改变。例如,在某些状态下,"In the Bimester"的第一个“块”可以有6行,第二个,7;但是,我无法用这第四个变量来区分。

期望:我想我的子集数据,按每个状态,子集只有第一个“豆腐块”,由每个州或第二“块”的行劈裂这两个"In the Bimester"

我有一个解决方案,使用data.table包,但我发现它有点差。有什么想法吗?

library(data.table) 
B <- as.data.table(B) 
B <- B[, .(Account, Value, index = 1:.N), by = .(State)] 
x <- B[Account == "Expenses", .(min_ind = min(index)), by = .(State)] 
B <- merge(B, x, by = "State") 
B <- B[index < min_ind & Account == "In the Bimester", .(Value), by = .(State)] 

您可以使用dplyr包:

library(dplyr) 
B %>% mutate(helper = data.table::rleid(Account)) %>% 
     filter(Account == "In the Bimester") %>% 
     group_by(State) %>% filter(helper == min(helper)) %>% select(-helper) 

# # A tibble: 6 x 3 
# # Groups: State [3] 
#  State   Account  Value 
#  <fctr>   <fctr>  <dbl> 
# 1 Arizona In the Bimester 0.17730148 
# 2 Arizona In the Bimester 0.05695585 
# 3 California In the Bimester 0.29089678 
# 4 California In the Bimester 0.86952723 
# 5  Texas In the Bimester 0.54076144 
# 6  Texas In the Bimester 0.59168138 

如果不是min您使用max你会得到"In the Bimester"最后出现的每个State。您也可以通过将最后一个管道更改为select(-helper,-Account)来排除Account列。

p.s.如果您不想使用data.table中的rleid,只需使用dplyr函数,请查看此thread