0

我有 data.frame 看起来像这样:

v1 <- c(1:10)
v2 <- c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
dfb <- data.frame(v1, v2)

> dfb
   v1    v2
1   1 FALSE
2   2 FALSE
3   3  TRUE
4   4 FALSE
5   5 FALSE
6   6 FALSE
7   7  TRUE
8   8 FALSE
9   9 FALSE
10 10 FALSE

我需要这些操作:

  1. 根据V2if将 data.frame 分割成区间TRUE
  2. 将是最后一个间隔元素V2的行TRUE
  3. 如果最后一个元素不是TRUE,它将被视为是(这可以通过添加TRUE到最后一个向量位置来轻松实现)
  4. 从创建的间隔打印V1为第一个和最后一个元素

完成此操作后,我的结果应如下所示:

  > df_final
   Vx Vy
    1 3
    4 7
    8 10

我已经尝试过cumsum向量v2,但TRUE值被视为第一个间隔元素而不是最后一个

> split(v2, cumsum(v2==TRUE))
$`0`
[1] FALSE FALSE

$`1`
[1]  TRUE FALSE FALSE FALSE

$`2`
[1]  TRUE FALSE FALSE FALSE
4

3 回答 3

1

获取 df_final

Vy <- c(which(dfb$v2 %in% T),nrow(dfb))
Vx <- c(1,Vy[-length(Vy)]+1)

df_final <- data.frame(Vx,Vy)

分裂 Df

library(data.table)

split_ind <- rleid(dfb$v2)-!(rleid(dfb$v2) %% 2)

split(dfb,split_ind)
于 2017-09-28T10:34:14.150 回答
1

我还将发布受 Eldioo 启发的答案,这个答案在V1非数值时也很有用,并且避免使用splitcumsum函数。

输入:

v1 <- letters[1:10]
v2 <- c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
dfb <- data.frame(v1, v2)

> dfb
   v1    v2
1   a FALSE
2   b FALSE
3   c  TRUE
4   d FALSE
5   e FALSE
6   f FALSE
7   g  TRUE
8   h FALSE
9   i FALSE
10  j FALSE

解决方案:

# data wrangling
library(data.table)
dfb["v3"] <- c(TRUE,dfb$v2[-length(dfb$v2)])
dfb["v4"] <- dfb$v2
dfb$v4[length(dfb$v4)] <- T
Vx <- which(dfb$v3)
Vy <- which(dfb$v4)
Vx <- dfb[Vx, ]$v1
Vy <- dfb[Vy, ]$v1

# for debugging purposes
dfb
   v1    v2    v3    v4
1   a FALSE  TRUE FALSE
2   b FALSE FALSE FALSE
3   c  TRUE FALSE  TRUE
4   d FALSE  TRUE FALSE
5   e FALSE FALSE FALSE
6   f FALSE FALSE FALSE
7   g  TRUE FALSE  TRUE
8   h FALSE  TRUE FALSE
9   i FALSE FALSE FALSE
10  j FALSE FALSE  TRUE

# final results
data.frame(Vx, Vy)
  Vx Vy
1  a  c
2  d  g
3  h  j
于 2017-10-05T11:20:31.383 回答
1

你仍然可以使用cumsum,你只需要稍微调整一下v2

v3 <- c(TRUE,v2[-length(v2)])
v3
 [1]  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

res <- split(v2,cumsum(v3))
res[[length(res)]][length(last(res))] <- T
res
$`1`
[1] FALSE FALSE  TRUE

$`2`
[1] FALSE FALSE FALSE  TRUE

$`3`
[1] FALSE FALSE  TRUE

df_final <- data.frame(Vx=which(v3),Vy=which(unlist(res,use.names=F)))
df_final
  Vx Vy
1  1  3
2  4  7
3  8 10
于 2017-09-28T11:01:39.763 回答