我的数据框看起来像:
X1 X2 X3
1 ### <NA> <NA>
2 aa bb cc
3 dd ee ff
4 ### <NA> <NA>
5 a1 a2 a3
6 b1 b2 b3
7 g3 h3 k5
8 ### <NA> <NA>
9 k1 k2 k3
是否可以通过###行将其拆分为3个小型data.frame列表:
[[1]]
X1 X2 X3
1 aa bb cc
2 dd ee ff
[[2]]
1 a1 a2 a3
2 b1 b2 b3
3 g3 h3 k5
[[3]]
1 k1 k2 k3
谢谢!
生成示例df的代码:
df=data.frame(rbind(c("###",NA,NA),c("aa","bb","cc"),c("dd","ee","ff"),c("###",NA,NA),c("a1","a2","a3"),c("b1","b2","b3"),c("g3","h3","k5"),c("###",NA,NA),c("k1","k2","k3")))
答案 0 :(得分:3)
使用g
对行进行分组,第一个数据框中的行为1,第二个数据行为2,依此类推。然后按g
拆分并删除每个组件中的第一行。
g <- cumsum(df$X1 == "###")
lapply(split(df, g), tail, -1)
,并提供:
$`1`
X1 X2 X3
2 aa bb cc
3 dd ee ff
$`2`
X1 X2 X3
5 a1 a2 a3
6 b1 b2 b3
7 g3 h3 k5
$`3`
X1 X2 X3
9 k1 k2 k3
或者,最后一行代码可以替换为(生成by
列表):
by(df, g, tail, -1)
答案 1 :(得分:2)
这可能有效:
from <- which(df[,"X1"]=="###")+1
to <- c(tail(from,-1)-2, nrow(df))
mapply(function(a,b) df[a:b,], from, to, SIMPLIFY=FALSE)
您需要检查角落情况(例如,如果第一行不是###
或最后一行有###
,该怎么办)。
答案 2 :(得分:2)
我们可以在使用逻辑split
vector
i1 <- df$X1 == "###"
split(df[!i1,], cumsum(i1)[!i1])