rdataframeappenddata-manipulationdata-management

Add a blank row to an R dataframe if a condition is met eleswhere in the dataframe


File here: https://github.com/pb865/exmaplefile

These are data from a behavioral task where 30 and 31 under the event code (ecode) column refer to responses and any that are less than 30 are stimuli. For some trials, participants did not respond in time after target stimuli (20, 21, and 22 ecodes), and so there is no response code associated. However, I need to add in some blank rows and indicate explicitly that no response was made on that trial.

What I've tried:

library(dplyr)
myevents = read.csv(data)

myevents2=myevents[myevents$ecode>=20 &  myevents$ecode<30 & lead(myevents$ecode<20),]
        
myrows = as.numeric(row.names(myevents2)
   
  for(i in 1:length(myrows)){
        myevents3 <- add_row(df, .after = i)
          }
                
myevents2=myevents[myevents$ecode>=20 &  myevents$ecode<30 & lead(myevents$ecode<20),]
        
        myrows=as.numeric(myevents2$item)
        
        myevents3=data.frame()
     
        
        for(i in 1:length(myevents$item)){
          if(myevents$item[i] %in% myrows){
            myevents3 <- add_row(myevents, .after=i)    
          }
        }

The final output should look the same, except with blank rows inserted after each of the rows in myevents that are included in the myevents2 subset of data.

Neither of these worked.What happened instead was that it added a blank row in the 1st position where one was indicated to be placed, then stopped.

I'm not quite sure where to go from here. Any help is appreciated!


Solution

  • To answer your question:

    df <- read.csv("data.csv")
    
    # Find the index of each row that satisfies the ecode constraint
    rows <- which(df$ecode < 30 & df$ecode >= 20)
    
    # Find all the object classes for each column
    column_classes <- sapply(df, class)
    
    # Construct a blank row representative of the dataframe using the switch() function
    blank_row <- as.data.frame(lapply(column_classes, function(class_type) {
      switch(class_type,
             "character" = "",
             "numeric" = NA_real_,
             "integer" = NA_integer_,
             "logical" = NA,
             "factor" = factor(levels = character(0)))
    }), stringsAsFactors = FALSE)
    
    # loop over rows inserting a blank row after every ith row
    for (i in rows){
        df <- add_row(df, blank_row, .after = i + 1)
    }
    

    I agree with @MrFlick that adding in blank rows is odd. From what you've framed in the question it sounds like you want to make your dataframe more readable by explicitly noting that error codes 20 <= ecode < 30 are codes that represent stimuli with no response in a reasonable amount of time.

    With that said I would suggest creating a new column to hold this data.