data.frame Error when attempting to populate specific rows

New to R Studio. I'm trying to read in excel file names and populate a data.frame:

#Let's say I've already read in a file name
counter <- 1 #simplifying as this would be a for loop that would start with a counter at 1
file_name <- "excel file name"
extension <- "xlsx"
status <-"successful"

#I initialize the data.frame and label the columns
global_file_list <- data.frame(File.Name = as.character(),
Extension = as.character(),
Status = as.character())

#When I try to populate this first row, I get the following warnings and the data.frame remains empty:
global_file_list[counter,] <- data.frame(cbind(file_name, extension, status))
Warning messages:
1: In [<-.factor(*tmp*, iseq, value = c(file_name = 1L)) :
invalid factor level, NA generated
2: In [<-.factor(*tmp*, iseq, value = c(file_ext = 1L)) :
invalid factor level, NA generated
3: In [<-.factor(*tmp*, iseq, value = c(status = 1L)) :
invalid factor level, NA generated

#However, if I were to do the following, without using the counter, the first row populates:
global_file_list <- data.frame(cbind(file_name, extension, status))

#Then this continues to work but populates the dataframe with N/A values
counter <- counter + 1
global_file_list[counter,] <- data.frame(cbind(file_name, extension, status))

  1. What is the reason the dataframe won't accept the first entry with a counter?
  2. Why does it populate with N/A instead of my variable values?

Thanks for your help!

Here is one way to start.

global_file_list <- data.frame(file_name = "excel file name", extension = "xlsx",status ="successful", stringsAsFactors = FALSE)

If you don't include stringsAsFactors = FALSE all three columns will be created as factors. You may want to change extension and status to factors at some point.

Trying to help you avoid having to discover what value of counter to use each time you want to append rows to the global list. Here is a pattern that use rbind.

global_file_list <- data.frame(file_name = "excel file name", extension = "xlsx",status ="successful", stringsAsFactors = FALSE)
next_file_list <- data.frame(file_name = "excel file name 2", extension = "xlsx",status ="successful", stringsAsFactors = FALSE)
global_file_list <- rbind(global_file_list,next_file_list)

That's the best I can do given you start with this "assumption".

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

Thanks for the response Phil. I tried stringsAsFactors and it works as you've written it but in my program the file_name, extension, and status are variables that change with every excel file read from an input folder. Because of that, I'm trying to add a row to the data.frame with each new file read by identifying the row with the counter variable. As such, I would write it as below (adding the notes with "..." to spare you of the code:

counter <- 1
global_file_list <- data.frame(File.Name = as.character(),
                           Extension = as.character(),
                           Status = as.character())

... start a for loop based on the number of files in the folder...
... read the file based on counter to get the below variables... (e.g. if counter = 1, read the 1st file in the folder, etc.)

file_name <- "some excel file name"
extension <- "could be xlsx or xls"
status <- "successful or unsuccessful"

#with this next line I attempt to input the 3 above variables into a new row in the dataframe

global_file_list[counter,] <- data.frame(cbind(file_name, extension, status),stringsAsFactors = FALSE)

counter <- counter + 1

...end for loop...

This addition of stringsAsFactors doesn't change the warning messages written in the original post and the row is populated with "NA" values.

Thanks again Phil. Combining your input with that of another brought me to the answer. The two issues in my code were:

  1. use stringsAsFactors during the initialization of the data.frame, not when attempting to input data into it (as I had tried that as well)
  2. there is no need to input the data to global_file_list by using the "data.frame" command again as I was doing "data.frame(cbind(..." It works with just the cbind.
1 Like