0

我想将这样的数据库分为两部分:

df <- data.frame(ID = c(1,1,1,1,1,2,2,2,3,3,3), 
ins =c(1,2,3,4,5,3,2,4,5,8,9),
Ytx = c(NA,NA,1998,NA,NA,NA,NA,NA,NA,2011,NA))

ID ins  Ytx
  1   1   NA
  1   2   NA
  1   3 1998
  1   4   NA
  1   5   NA
  2   3   NA
  2   2   NA
  2   4   NA
  3   5   NA
  3   8 2011
  3   9   NA

第一个应该是这样的(在 Ytx 出现后出现的所有值都按 ID 分组):

 ID ins  Ytx
  1   3 1998
  1   4   NA
  1   5   NA
  3   8 2011
  3   9   NA

另一个由剩下的东西制成:

ID ins  Ytx
  1   1   NA
  1   2   NA
  2   3   NA
  2   2   NA
  2   4   NA
  3   5   NA

谢谢您的支持

4

3 回答 3

2

在基数 R 中,我们可以使用aveand split。这会将数据分成两个列表。第一个是值之前的数据,Ytx第二个是之后的行Ytx

split(df, with(df, ave(!is.na(Ytx), ID, FUN = cumsum)))
#Or if you may have multiple Ytx per ID
#split(df, with(df, ave(!is.na(Ytx), ID, FUN = cumsum)) > 0)

#$`0`
#  ID ins Ytx
#1  1   1  NA
#2  1   2  NA
#6  2   3  NA
#7  2   2  NA
#8  2   4  NA
#9  3   5  NA

#$`1`
#   ID ins  Ytx
#3   1   3 1998
#4   1   4   NA
#5   1   5   NA
#10  3   8 2011
#11  3   9   NA
于 2019-12-19T03:56:59.867 回答
2

的另外两个替代方案:

# convert 'df' tot a 'data.table'
library(data.table)
setDT(df)

# alternative 1
split(df, df[, !!cumsum(!is.na(Ytx)), by = ID]$V1)

# alternative 2
split(df, df[, !!Reduce(`+`, !is.na(Ytx), accumulate = TRUE), by = ID]$V1)

两者都给出:

$`FALSE`
   ID ins Ytx
1:  1   1  NA
2:  1   2  NA
3:  2   3  NA
4:  2   2  NA
5:  2   4  NA
6:  3   5  NA

$`TRUE`
   ID ins  Ytx
1:  1   3 1998
2:  1   4   NA
3:  1   5   NA
4:  3   8 2011
5:  3   9   NA
于 2019-12-19T07:12:08.887 回答
0

这是使用的选项data.table

setDT(df)[, rn := .I]
idx <- df[, 
    if (any(!is.na(Ytx))) 
        .I[seq(.N) >= match(TRUE, !is.na(Ytx))]
, ID]$V1

df[idx]

   ID ins  Ytx rn
1:  1   3 1998  3
2:  1   4   NA  4
3:  1   5   NA  5
4:  3   8 2011 10
5:  3   9   NA 11

df[-idx]

   ID ins Ytx rn
1:  1   1  NA  1
2:  1   2  NA  2
3:  2   3  NA  6
4:  2   2  NA  7
5:  2   4  NA  8
6:  3   5  NA  9

数据:

library(data.table)
df <- data.frame(ID = c(1,1,1,1,1,2,2,2,3,3,3), 
    ins =c(1,2,3,4,5,3,2,4,5,8,9),
    Ytx = c(NA,NA,1998,NA,NA,NA,NA,NA,NA,2011,NA))
于 2019-12-19T05:35:50.893 回答