根据特定数值序列创建子集

4
我有一个数据框,长这样:
df <- data.frame(x = c(0:20), y = c(50:70),
                 m = c(0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0 ,0 , -1, 0, 0, 1, 0, 0, -1, 0))

我想创建由'm'列中的一系列值定义的子集:

一个序列应该以m == -1开始和结束,并且在起始和结尾-1之间必须有一个1。然后,每个子集都包括在开始结束之间的所有行。

例如,上述数据中的一个子集将如下所示:

Subset1 <- data.frame(x = c(4:10), y = c(54:60), m = c(-1, 0, 0, 1, 0, 0, -1))
#    x  y  m
# 1  4 54 -1 # starts with -1
# 2  5 55  0
# 3  6 56  0
# 4  7 57  1 # contains a 1
# 5  8 58  0
# 6  9 59  0
# 7 10 60 -1 # ends with -1

我一直在尝试,但是无法弄清如何做到。我尝试使用mapplyfor循环,但当涉及到设置模式时,我总是卡住,因为模式的两端是相同的。

例如,使用mapply,我已经完成了:

List_subsets <- mapply(function(i, j, z) df[i:j:z, , drop = FALSE], -1, 1, -1,
                       SIMPLIFY = FALSE)

当然了,我总是能够获得最好的
# error: In i:j:z : numerical expression has 3 elements: only the first used

你知道这是否可能,并且能帮我吗?我非常感激您的回答,因为我对R非常陌生,它对我来说非常具有挑战性。

非常感谢!


你寻求的最终输出格式是什么? - AnilGoyal
最好提供一个子集列表,这样我就可以单独迭代其中的某个函数。 - loki
谢谢您提出这个好问题。如果您有一个序列'm',如c(-1, 1, -1, 1, -1),那么假设第二个-1被以第一个-1开头的子集所“消耗”,那么我们只有一个组/子集,即第1-3行?或者它可以是两个共享“-1”的组,其中第1-3行是一组,第3-5行是另一组?您能否澄清一下。谢谢。 - Henrik
1个回答

3
你可以尝试这个方法,如果它能达到你的期望,请告诉我:
library(stringr)
pattrn <- data.frame(str_locate_all(paste0(df$m+1,collapse=''),'0[1]*?2[1]*?0')[[1]])
## str_locate_all will find all start and end of the pattern -1,1,-1
## to find -1, 1, -1 , I have added 1 to the column, this will remove the negative sign for correct capture of location
## so, the new pattern to be found is 0,2,0, to do this I concatenated the m column and try to find the 0, 2, 0 with regex mentioned
pattrn_rows <- Map(seq, from=pattrn$start, to=pattrn$end)
## converting to data.frame
lapply(pattrn_rows,function(x)df[x,])
## finally subsetting, this step will give the final result into two lists of dataframes

输出:

[[1]]
    x  y  m
5   4 54 -1
6   5 55  0
7   6 56  0
8   7 57  1
9   8 58  0
10  9 59  0
11 10 60 -1

[[2]]
    x  y  m
14 13 63 -1
15 14 64  0
16 15 65  0
17 16 66  1
18 17 67  0
19 18 68  0
20 19 69 -1

1
是的,那非常好!非常感谢您的时间和快速回复!!! - loki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接