【问题标题】:Select rows of ids that have a pattern without losing the other rows选择具有模式的 id 行而不丢失其他行
【发布时间】:2019-03-30 15:21:10
【问题描述】:

我有以下数据框:

# Example:
_________________________
     | id  | day  | state
-------------------------

 [1,]    1    0    0
 [2,]    1    1    0
 [3,]    1    2    0
 [4,]    1    3    1
 [5,]    1    4    1
 [6,]    1    5    1
 [7,]    1    6    0
 [8,]    1    7    0
 [9,]    1    8    3
[10,]    2    0    0
[11,]    2    1    0
[12,]    2    2    0
[13,]    2    3    1
[14,]    2    4    1
[15,]    2    5    4
[16,]    3    0    0
[17,]    3    1    0
[18,]    3    2    1
[19,]    3    3    0
[20,]    3    4    4
[21,]    4    0    0
[22,]    4    1    1
[23,]    4    2    0
[24,]    4    3    0
[25,]    4    4    0
[26,]    4    5    1
[27,]    4    6    0
[28,]    4    7    3
[29,]    5    0    0
[30,]    5    1    1
[31,]    5    2    1
[32,]    5    3    0
[33,]    5    4    0
[34,]    5    5    4

# Code:
byRow <- TRUE

example.Matrix <- matrix(data = c(1, 0, 0,1, 1, 0,1, 2, 0,1, 3, 1,1, 4, 1,1, 5, 1,1, 6, 
0,1, 7, 0,1, 8, 3,2, 0, 0,2, 1, 0, 2, 2, 0, 2, 3, 1,2, 4, 1,2, 5, 4, 3, 0, 0,3,1, 0,3, 
2, 1,3, 3, 0,3, 4, 4,4, 0, 0, 4, 1, 1, 4, 2, 0,4, 3, 0,4, 4, 0,4, 5, 1,4, 6, 0,4, 7, 3,
5, 0, 0,5, 1, 1,5, 2, 1, 5, 3, 0, 5, 4, 0,5, 5, 4), byrow=TRUE,ncol=3)

example.df<-as.data.frame(example.Matrix)

colnames(example.df) <- c("id", "day", "states")

我想做以下事情:

1) 创建一个数据框(或矩阵),其 id 在状态中只有唯一值 1,后跟除 1 之外的下一行中的任何值。例如,它看起来像这样:

# Expected output for first step:
_______________
|id|day|states|
----------------
3  | 2 |   1  |
3  | 3 |   0  |  
3  | 4 |   4  |  
----------------

# Example in code:
matrix.1<-matrix(c(3,2,1,3,3,0,3,4,4), byrow=TRUE,ncol=3)
df.1<-as.data.frame(matrix.1)
colnames(df.1) <- c("id", "day", "states")

请注意,在 id 4 中,尽管存在状态从 1 变为 0 的情况,但它们会重新进入 1,因此 id 4 不应包含在新的数据帧/矩阵中。

# Should not be included in expected output for df.1:
_______________
|id|day|states|
----------------
4  | 1 |   1  | #* start 
4  | 2 |   0  | #* meets condition
4  | 3 |   0  | 
4  | 4 |   0  | 
4  | 5 |   0  | 
4  | 6 |   1  | #*reenters 1 - does not meet condition
4  | 7 |   0  | 
4  | 8 |   3  | 
---------------

2) 然后,一旦构建了该数据框/矩阵,我想从原始数据框制作另一个数据框(例如,使用 for 循环),但这次条件适用于在状态中具有以下模式的个人: 1,然后是 1,然后是除 1 以外的任何值。看起来像这样:

# Expected  output from second step:
_______________
|id|day|states|
----------------
2  | 3 |   1  |
2  | 4 |   1  |  
2  | 5 |   4  |  
5  | 1 |   1  |
5  | 2 |   1  |  
5  | 3 |   0  |  
5  | 4 |   0  |
5  | 5 |   4  |    
----------------

同样ids在满足条件后不应该重新进入1

3) 之后我想继续重复这种模式,所以下一个将针对处于以下状态的个人:1,然后是 1,然后是 1,然后是除 1 之外的任何内容:

# Expected output from third step:
_______________
|id|day|states|
----------------
1  | 3 |   1  |
1  | 4 |   1  |  
1  | 5 |   1  |  
1  | 6 |   0  |
1  | 7 |   0  |  
1  | 8 |   3  |   
----------------

4) 然后我将继续这个模式直到 29 个连续的 1。

所以最后我希望有 30 个数据框/矩阵与符合上述条件的个人。

【问题讨论】:

  • "id" 1 有 1,1,1,0 它有一个由三个 1 组成的序列,它必须是唯一的 1,然后是后面不是 1 的任何数字。所以 1,x.. . 将是第一个输出中感兴趣的模式,然后是 1,1,x... 在下一个输出中然后是 1,1,1,x... 在下一个输出中然后是 1,1,1,1,x。 ..等等。这就是为什么“id”1 不适用于第一个输出的原因。

标签: r grouping unique rows


【解决方案1】:

我们为此创建了一个函数

library(data.table)
library(dplyr)
f1 <- function(data, n){
    ids <- data %>%
             mutate(stateslead = lead(states, default = last(states))) %>%
             group_by(grp = rleid(states == 1)) %>% 
             filter(n() == n, states == 1, stateslead != 1) %>%     
             group_by(id) %>%     
             filter(n() == 1) %>%
             pull(id)

    data %>%
       filter(id %in% ids) %>%
       group_by(id) %>% 
       filter(cumsum(states) > 0)



 }

-测试

f1(example.df, 1)
#  id day states
#1  3   2      1
#2  3   3      0
#3  3   4      4

f1(example.df, 2)
# A tibble: 8 x 3
# Groups:   id [2]
#     id   day states
#  <dbl> <dbl>  <dbl>
#1     2     3      1
#2     2     4      1
#3     2     5      4
#4     5     1      1
#5     5     2      1
#6     5     3      0
#7     5     4      0
#8     5     5      4

f1(example.df, 3)
#  id day states
#1  1   3      1
#2  1   4      1
#3  1   5      1
#4  1   6      0
#5  1   7      0
#6  1   8      3

另外,如果我们想一步完成,请使用map 循环遍历“n”

library(purrr)
out1 <- map(1:3, f1, data = example.df)

对于 OP,1:3 可以替换为 1:29。 'out1' 是 listtibble/data.frames

【讨论】:

  • 谢谢阿克伦。虽然这似乎适用于该示例,但它并没有设法对完整的数据集做同样的事情。也就是说,我将尝试看看您使用的方法是否可以阐明解决方案。也非常感谢您花时间提出解决方案。
  • akrun,用你的代码我能够得到我需要的东西,我只需要对我正在使用的数据集进行一些调整。非常感谢您的帮助。
猜你喜欢
  • 2018-05-06
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多