Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a R function for preparing datasets for survival analysis like stset in Stata?

Datasets look like this

id  start   end  failure x1
 1    0      1      0    0
 1    1      3      0    0
 1    3      6      1    0
 2    0      1      1    1
 2    1      3      1    1
 2    3      4      0    1
 2    4      6      0    1
 2    6      7      1    1

As you see, when id = 1, it's just the data input to coxph in survival package. However, when id = 2, at the beginning and end, failure occurs, but in the middle, failure disappears.

Is there a general function to extract data from id = 2 and get the result like id = 1?

I think when id = 2, the result should look like below.

id  start   end  failure x1
1    0      1      0    0
1    1      3      0    0
1    3      6      1    0
2    3      4      0    1
2    4      6      0    1
2    6      7      1    1

like image 474
S.X Avatar asked Jan 25 '26 02:01

S.X


1 Answers

A bit hacky, but should get the job done.

Data:

# Load data
library(tidyverse)
df <- read_table("
 id   start  end    failure  x1
 1    0      1      0        0
 1    1      3      0        0
 1    3      6      1        0
 2    0      1      1        1
 2    1      3      1        1
 2    3      4      0        1
 2    4      6      0        1
 2    6      7      1        1
") 

Data wrangling:

# Check for sub-groups within IDs and remove all but the last one
df <- df %>%
    # Group by ID
    group_by(
        id
    ) %>%
    mutate(
        # Check if a new sub-group is starting (after a failure)
        new_group = case_when(
            # First row is always group 0
            row_number() == 1 ~ 0,
            # If previous row was a failure, then a new sub-group starts here
            lag(failure) == 1 ~ 1,
            # Otherwise not
            TRUE ~ 0
        ),
        # Assign sub-group number by calculating cumulative sums
        group = cumsum(new_group)
    ) %>%
    # Keep only last sub-group for each ID
    filter(
        group == max(group)
    ) %>%
    ungroup() %>%
    # Remove working columns
    select(
        -new_group, -group
    )

Result:

> df
# A tibble: 6 × 5
     id start   end failure    x1
  <dbl> <dbl> <dbl>   <dbl> <dbl>
1     1     0     1       0     0
2     1     1     3       0     0
3     1     3     6       1     0
4     2     3     4       0     1
5     2     4     6       0     1
6     2     6     7       1     1
like image 193
Roman Avatar answered Jan 26 '26 17:01

Roman