Remove factor level from data frame inside a function

Viewed 44

I want to get my data frames ready before start working with them. In my data I have two factor variables (factorVAR1, factorVAR2) of interest and one metric variabel (VAR)

So I wanted to program a function that remove factor levels that have less than 3 observations and remove these from each data frame. If in the end, those data frames that less than two factor levels then I want to delete these frame from the list (because than I cannot compare different groups with each other).

I think the problem arise already in line 13 when I do not have any factor levels to remove...

split_frames<- function(OG_DF,factorVAR1, factorVAR2 ,VAR, frame_name){
  #OG_DF$keyno <- row.names(OG_DF)
  splitted <- split(OG_DF, as.factor(OG_DF[,factorVAR1]))
  new_names <- c(paste0(unlist(levels(as.factor(OG_DF[,factorVAR1]))),frame_name))
  
  for (i in 1:length(splitted)) { 
    # Remove those entries that contain NA in the variabel of interest:
    splitted[[i]] <- droplevels(splitted[[i]][!(is.na(splitted[[i]][,VAR])),])
    DF <- as.data.frame(table(droplevels(as.factor(splitted[[i]][,factorVAR2]))))
    
    # Only keep those factor levels in the data frame that contain more than 3 entries, else should be excluded 
    # from the data frame
    fct_removal <- as.vector(DF[which(DF$Freq > 3),]$Var1)
 
# I don't know how to remove a specific factor level from a data frame by a vector:
# 
# this?
    splitted[[i]]  <- splitted[[i]]  %>% filter(droplevels(as.factor(splitted[[i]][,factorVAR2])) %in% fct_removal)
   
# this??? 
    splitted[[i]] <- droplevels(splitted[[i]][-which(splitted[[i]][,(as.factor(factorVAR1)),] %in% fct_removal) ,])
 
# Then the the remaining code runs:
    N_levels <- nlevels(droplevels(as.factor(splitted[[i]][,factorVAR1])))
    
    # If the number of factor levels has dropped to less than 2, remove data frame from list:
    if (N_levels < 2) {
      warning("The data frame ",new_names[i]," is excluded from further analysis \n 
              because it does not contain all factor levels needed.\n")
      splitted[[i]] <- NA
      
    }
    
    # if number of factor levels is greater or equal 2, than the data frame is ready for analysis
    else {
      assign(new_names[i], splitted[[i]], envir=.GlobalEnv)
          message("Analysis ready")
          } 
  }
}

Can someone help?

1 Answers

Here is own solution:

split_frames<- function(OG_DF,factorVAR1, factorVAR2 ,VAR, frame_name){
  #OG_DF$keyno <- row.names(OG_DF)
  splitted <- split(OG_DF, as.factor(OG_DF[,factorVAR1]))
  new_names <- c(paste0(unlist(levels(as.factor(OG_DF[,factorVAR1]))),frame_name))
  
  for (i in 1:length(splitted)) { 
    # Remove those entries that contain NA in the variabel of interest:
    splitted[[i]] <- droplevels(splitted[[i]][!(is.na(splitted[[i]][,VAR])),])
    OG_entries <- nrow(splitted[[i]][!(is.na(splitted[[i]][,VAR])),])
    if (OG_entries < 3) {warning("Not enough data in: ", new_names[i]) 
      next}
    
    DF <- as.data.frame(table(droplevels(as.factor(splitted[[i]][,factorVAR2]))))
    
    # Only keep those factor levels in the data frame that contain more than 3 entries, else should be excluded 
    # from the data frame
    fct_removal <- as.vector(DF[which(DF$Freq < 3),]$Var1)
    ID <- which(splitted[[i]][,(as.factor(factorVAR1))] %in% fct_removal)
    if (length(ID) > 1) {splitted[[i]] <-splitted[[i]][-ID,]}
    N_levels <- nlevels(droplevels(as.factor(splitted[[i]][,factorVAR2])))
    
    # If the number of factor levels has dropped to less than 2, remove data frame from list:
    if (N_levels < 2) {
      warning("The data frame ",new_names[i]," is excluded from further analysis because it does not contain all factor levels needed.\n")
      splitted[[i]] <- NA
      next
      
    }
    
    # if number of factor levels is greater or equal 2, than the data frame is ready for analysis
    else {
      final_nrow <- nrow(splitted[[i]])
      assign(new_names[i], splitted[[i]], envir=.GlobalEnv)
          message("Data frame ",new_names[i]," is ready. ",OG_entries-final_nrow," entries were removed.\n")
          } 
  }
}
Related