0
$\begingroup$

For example, I have a data frame consisting of columns ID, Genotype, Sex, time (days), event (deaths), for a number of Drosophila strains of both sexes, where deaths can be anywhere from 0 to 2, 3, etc. Apologies as this is probably a very simple solution, but most tutorials about survival analysis don't answer it and only use datasets where the event is either 0 or 1. Have tried typical loading of data frame and packages (this part seems fine) and then assign survival object and plot with ggsurvplot.

$\endgroup$
3
  • 4
    $\begingroup$ You have an aggregated dataset. Expand it into an individual level dataset. Then run a standard survival analysis. For example, if you a record with three deaths, convert this to three records, each with a single death event.. In fact, the way you describe your data, it sounds like you don’t have any censoring events. If so, you don’t really need survival analysis… $\endgroup$
    – Limey
    Commented Jun 29, 2023 at 5:26
  • $\begingroup$ @Limey thanks! Any recommendations on how to do that? $\endgroup$
    – Plsnobully
    Commented Jun 29, 2023 at 15:06
  • $\begingroup$ Poisson regression might be able to handle that. Why don't you post a sample dataset? Tested code is more likely to be offered when we have an unambiguous example on which we might apply methods. $\endgroup$
    – DWin
    Commented Jul 1, 2023 at 3:36

2 Answers 2

1
$\begingroup$

Expanding the data set into one row per individual, as suggested in a comment and in another answer, is a very good choice in this situation and should be both reliable and extensible to more complicated situations.

For reference, it's also possible to use the weights argument to the R coxph() function to accomplish this. According to the help page:

Case weights are treated as replication weights, i.e., a case weight of 2 is equivalent to having 2 copies of that subject's observation.

In your situation, you would have an event marker of 1 for death at a particular time and set of covariate values in a data row, but specify the number of individuals having the event and that set of covariate values as the weight value in that row. You could similarly use the weights argument, with an event marker of 0, for the number of flies that survived to the final observation time, for each set of covariate values.

$\endgroup$
0
$\begingroup$

Assuming your survival data looks like this:

ID Genotype Sex time (days) event (deaths)
Control_Vial1 Control F 10 1
Control_Vial2 Control M 10 1

Option 1: Use the ggbulksurv package at https://github.com/qhuitan/ggbulksurv - I wrote it specifically for this scenario. ggbulksurv::get_indiv_surv() would do the trick.

In order to make your data work with this package, you have to add a column called condition which would reflect the sex. Your input data should look like this:

condition ID Genotype Sex day dead
control_F Control_Vial1 Control F 10 3
control_M Control_Vial2 Control M 10 2

Option 2: Manually code this using tidyr::uncount()

I'm assuming you have no censored data (that is, no flies have escaped/ gone missing/ gotten stuck in food).

Renaming some columns for easy reference:

ID genotype sex day dead
Control_Vial1 Control F 10 3
Control_Vial2 Control M 10 2
sample_data <- read.csv("path-to-file.csv")

# Add a condition column
sample_data <- sample_data %>% 
                tidyr::unite("condition", genotype:sex, remove = FALSE)


## -- Calculate dead -- ##
  df_dead <- sample_data %>%
    # Select only dead column
    dplyr::group_by(condition) %>%
    # Uncount so that each row becomes an individual
    tidyr::uncount(dead) %>%
    # Add status = 1 (dead)
    dplyr::mutate(status = 1)

If you have censored data, use this code instead:

ID genotype sex day dead censored
Control_Vial1 Control F 10 3 2
Control_Vial2 Control M 10 2 5
 ## -- Calculate dead -- ##
  df_dead <- sample_data %>%
    # Select only dead column
    dplyr::group_by(condition) %>%
    dplyr::select(-c(censored)) %>%
    # Uncount so that each row becomes an individual
    tidyr::uncount(dead) %>%
    # Add status = 1 (dead)
    dplyr::mutate(status = 1)

  ## -- Calculate censored -- ##
  df_censored <- sample_data %>%
    # Select only censored column
    dplyr::group_by(condition) %>%
    dplyr::select(-c(dead)) %>%
    # Uncount so that each row becomes an individual
    tidyr::uncount(censored) %>%
    # Add status = 0 (censored)
    dplyr::mutate(status = 0)

  ## -- Combine -- ##
  df_combined <- dplyr::full_join(df_censored, df_dead,
                           join_by("condition", "day", "status")) %>%
    dplyr::arrange(day) %>%
    dplyr::ungroup()

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.