Body: <p>I'm quite new to R and biostatistics. I need to work out the p values from the survival analysis (log rank test) for two thousand possible different combinations of events over a 11 year period. I have code that works if I know the exact combination of numbers of events but I don't know how to adapt the code with a loop or a function to make it repeat the whole thing and give me just the result of the p-values. I've asked chatGPT but to no avail.</p>
  <p>Essentially, I have two populations: a study and a control population. I start with a vector for time <code>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)</code>. I also have a vector for the number of drop-outs/deaths i.e. censoring for each of these years for both the study and the control population, and I know exactly what is in those vectors. I also know exactly what is in the vector that contains the number of events per year (in my case the event is a diagnosis of diabetic retinopathy) for the control population. Then I have a vector with the events per year for the study population and the problem is I don't exactly know the combination of events. I have a dataframe with &gt;2000 possible combinations of events per year, with each row containing a possible combination of events that could be in the study events vector.</p>
  <p>The sequence then would make two dataframes, one for the study population with time (1:11), number of censorings per year and number of events per year, and one for the control population with the same columns. To do survival analysis, each of these dataframes needs to be transformed such that each event (represented by a 1) or each censoring (represented by a 0) is on a separate row. That means that the two dataframes (study and control) have many more rows than the initial dataframes (but the events and censoring appear in the same column). I then need to add a column to each dataframe to label them as group 1 or group 2 so that the survival analysis can compare them. I then perform the log rank test.</p>
  <p>As you will see from the code below, I have the sequence to make the dataframes, transform them, combine them and undertake the log rank test, but what I don't know is how to undertake the whole sequence using each row of another dataframe (let's call it 'combinations') in the vector <code>number_study_events</code>. At the end of this I need to pull out all the p-values from the log rank tests and make a list, vector or dataframe of them, that is actually all I need. I would be grateful for advice!</p>
  <pre class="lang-r prettyprint-override"><code># Load survival package
  library(survival)
  # create variables 
  time &lt;- c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
  number_study_events &lt;- c(???) ### each row of the dataframe with all possible combinations needs to appear in this vector
  number_study_censoring &lt;- c(0, 5, 11, 8, 18, 14, 8, 10, 6, 10, 10)
  number_control_events &lt;- c(91, 49, 63, 62, 70, 133, 119, 159, 154, 110, 137)
  number_control_censoring (0, 1966, 1871, 2739, 2428, 2196, 1792, 1732, 1493, 1309, 1599)
  
  # create 2 initial dataframes
  time_events_study &lt;- data.frame(time, number_study_events, no_study_ censoring)
  time_events_control &lt;- data.frame(time, number_control_events, number_control_censoring)
  
  #expand dataframe to make one event per row for KM analysis
        
   #study - create expanded dataframe for study population
  # Create an empty dataframe to store the transformed data
  transformed_df_study &lt;- data.frame()
  
  # Loop through each row of the original dataframe
  for (i in 1:nrow(time_study_events)) {
   # Add rows for events
   transformed_study_events &lt;- rbind(transformed_study_events, data.frame(
    time = rep(time_events_study[],time[i],timestudyeventstime[i], time_study_eventsnumber_study_events[i]), # Repeat time for each event
    event = rep(1,time_events_study$number_study_events[i]) # Indicator variable for events (1)
   ))
   
   # Add rows for censoring events
   transformed_df_study &lt;- rbind(transformed_df_study, data.frame(
    time = rep(time_events_study[],time[i],timeeventsstudytime[i], time_events_studynumber_study_censoring[i]), # Repeat time for each censoring event
    event = rep(0, time_events_study$number_study_censoring[i]) # Indicator variable for censoring (0)
   ))
  }
  
  #CONTROL - create transformed dataframe
  # Create an empty dataframe to store the transformed data
  transformed_df_control &lt;- data.frame()
  
  # Loop through each row of the original dataframe
  for (i in 1:nrow(time_events_control)) {
   # Add rows for events
   transformed_df_control &lt;- rbind(transformed_df_control, data.frame(
    time = rep(time_events_control[],time[i],timeeventscontroltime[i], time_events_controlnumber_control_events[i]), # Repeat time for each event
    event = rep(1,time_events_control$number_control_events[i]) # Indicator variable for events (1)
   ))
   
   # Add rows for censoring events
   transformed_df_control &lt;- rbind(transformed_dr_control, data.frame(
    time = rep(time_events_ndm_nafl[],time[i],timeeventscontroltime[i], time_events_controlnumber_control_censoring[i]), # Repeat time for each censoring event
    event = rep(0, time_events_control$number_control_censoring[i]) # Indicator variable for censoring (0)
   ))
  }
  
  # Add a new variable 'group' to each dataframe to indicate the group
  transformed_df_control&lt;−&quot;1&quot;group&lt;−&quot;Group1&quot;transformeddfstudygroup &lt;- &quot;Group 1&quot;
  transformed_df_studygroup &lt;- &quot;Group 2&quot;
  
  # Combine the data from both dataframes
  combined_data_nafl &lt;- rbind(transformed_df_control, transformed_df_study)
  
  # Fit the Kaplan-Meier curves with confidence intervals
  fit_with_ci_nafl &lt;- survfit(Surv(time, event) ~ group, data = combined_data_nafl, conf.int = TRUE)
             
  #log rank
  result &lt;- survdiff(Surv(time, event) ~ group, data = combined_data_nafl)
  print(result)
  </code></pre>
  <p>In my case time actually starts at 2, in the example above, but it doesn't matter, it could start at 1 and go up to 11, as per example above.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-04-08T09:47:11.333Z
Comments.Text: Please add anything you need to add to the question. No need for a special "edit:" section, we have an edit history if anyone needs to see the old version, just edit it into the flow of the question so all information is contained in the question itself.
Comments.UserDisplayName: terdon
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-04-16T12:48:56.040Z
Comments.Text: try to summarize your question, and prepare a minimal example. It's not very inviting going through 66 lines of code written by somebody else while trying to understand what they do (you made a good effort trying to explain what you want to achieve, though. However, I believe your lengthy description alienates potential readers).
Comments.UserDisplayName: ssayols
Tags: <r><biostatistics>
Title: How do I get R to repeat the same sequence of commands to the 2000 rows of a dataframe (each row being turned into a vetor) to give me 2000 p values?
ThreadText: # How do I get R to repeat the same sequence of commands to the 2000 rows of a dataframe (each row being turned into a vetor) to give me 2000 p values?
  
  (Asked by: username_0 on 2024-04-07)
  
  I'm quite new to R and biostatistics. I need to work out the p values from the survival analysis (log rank test) for two thousand possible different combinations of events over a 11 year period. I have code that works if I know the exact combination of numbers of events but I don't know how to adapt the code with a loop or a function to make it repeat the whole thing and give me just the result of the p-values. I've asked chatGPT but to no avail.
  
  Essentially, I have two populations: a study and a control population. I start with a vector for time `(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)`. I also have a vector for the number of drop-outs/deaths i.e. censoring for each of these years for both the study and the control population, and I know exactly what is in those vectors. I also know exactly what is in the vector that contains the number of events per year (in my case the event is a diagnosis of diabetic retinopathy) for the control population. Then I have a vector with the events per year for the study population and the problem is I don't exactly know the combination of events. I have a dataframe with >2000 possible combinations of events per year, with each row containing a possible combination of events that could be in the study events vector.
  
  The sequence then would make two dataframes, one for the study population with time (1:11), number of censorings per year and number of events per year, and one for the control population with the same columns. To do survival analysis, each of these dataframes needs to be transformed such that each event (represented by a 1) or each censoring (represented by a 0) is on a separate row. That means that the two dataframes (study and control) have many more rows than the initial dataframes (but the events and censoring appear in the same column). I then need to add a column to each dataframe to label them as group 1 or group 2 so that the survival analysis can compare them. I then perform the log rank test.
  
  As you will see from the code below, I have the sequence to make the dataframes, transform them, combine them and undertake the log rank test, but what I don't know is how to undertake the whole sequence using each row of another dataframe (let's call it 'combinations') in the vector `number_study_events`. At the end of this I need to pull out all the p-values from the log rank tests and make a list, vector or dataframe of them, that is actually all I need. I would be grateful for advice!
  
  ```r
  # Load survival package
  library(survival)
  # create variables 
  time <- c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
  number_study_events <- c(???) ### each row of the dataframe with all possible combinations needs to appear in this vector
  number_study_censoring <- c(0, 5, 11, 8, 18, 14, 8, 10, 6, 10, 10)
  number_control_events <- c(91, 49, 63, 62, 70, 133, 119, 159, 154, 110, 137)
  number_control_censoring (0, 1966, 1871, 2739, 2428, 2196, 1792, 1732, 1493, 1309, 1599)
  
  # create 2 initial dataframes
  time_events_study <- data.frame(time, number_study_events, no_study_ censoring)
  time_events_control <- data.frame(time, number_control_events, number_control_censoring)
  
  #expand dataframe to make one event per row for KM analysis
        
   #study - create expanded dataframe for study population
  # Create an empty dataframe to store the transformed data
  transformed_df_study <- data.frame()
  
  # Loop through each row of the original dataframe
  for (i in 1:nrow(time_study_events)) {
   # Add rows for events
   transformed_study_events <- rbind(transformed_study_events, data.frame(
    time = rep(time_events_study[],time[i],timestudyeventstime[i], time_study_eventsnumber_study_events[i]), # Repeat time for each event
    event = rep(1,time_events_study$number_study_events[i]) # Indicator variable for events (1)
   ))
   
   # Add rows for censoring events
   transformed_df_study <- rbind(transformed_df_study, data.frame(
    time = rep(time_events_study[],time[i],timeeventsstudytime[i], time_events_studynumber_study_censoring[i]), # Repeat time for each censoring event
    event = rep(0, time_events_study$number_study_censoring[i]) # Indicator variable for censoring (0)
   ))
  }
  
  #CONTROL - create transformed dataframe
  # Create an empty dataframe to store the transformed data
  transformed_df_control <- data.frame()
  
  # Loop through each row of the original dataframe
  for (i in 1:nrow(time_events_control)) {
   # Add rows for events
   transformed_df_control <- rbind(transformed_df_control, data.frame(
    time = rep(time_events_control[],time[i],timeeventscontroltime[i], time_events_controlnumber_control_events[i]), # Repeat time for each event
    event = rep(1,time_events_control$number_control_events[i]) # Indicator variable for events (1)
   ))
   
   # Add rows for censoring events
   transformed_df_control <- rbind(transformed_dr_control, data.frame(
    time = rep(time_events_ndm_nafl[],time[i],timeeventscontroltime[i], time_events_controlnumber_control_censoring[i]), # Repeat time for each censoring event
    event = rep(0, time_events_control$number_control_censoring[i]) # Indicator variable for censoring (0)
   ))
  }
  
  # Add a new variable 'group' to each dataframe to indicate the group
  transformed_df_control<−"1"group<−"Group1"transformeddfstudygroup <- "Group 1"
  transformed_df_studygroup <- "Group 2"
  
  # Combine the data from both dataframes
  combined_data_nafl <- rbind(transformed_df_control, transformed_df_study)
  
  # Fit the Kaplan-Meier curves with confidence intervals
  fit_with_ci_nafl <- survfit(Surv(time, event) ~ group, data = combined_data_nafl, conf.int = TRUE)
             
  #log rank
  result <- survdiff(Surv(time, event) ~ group, data = combined_data_nafl)
  print(result)
  
  ```
  
  In my case time actually starts at 2, in the example above, but it doesn't matter, it could start at 1 and go up to 11, as per example above.
  
  **Tags:** r, biostatistics
  
  > **Comments:**
  > **username_1**: Please add anything you need to add to the question. No need for a special "edit:" section, we have an edit history if anyone needs to see the old version, just edit it into the flow of the question so all information is contained in the question itself.  
  > **username_2**: try to summarize your question, and prepare a minimal example. It's not very inviting going through 66 lines of code written by somebody else while trying to understand what they do (you made a good effort trying to explain what you want to achieve, though. However, I believe your lengthy description alienates potential readers).  
  
  ---
  
  ## 0 answers
  
  