简体   繁体   中英

Extracting and merging dataframes from an S4 class list in R

I have an S4 class list (called vi2). This is the first segment of it:

  • @variables: chr [1:7]
  • @vImplist: list of 400
    • $1: Formal class '.vImp' with 2 slots
      • @Variables: chr [1:7]
      • @vImp: 'data.frame': 7 bs. of 3 variables:
        • $variables:Factor w/ 7 levels
          • $Ctest: num [1:7]
          • $Atest: num [1:7]
    • $2: Formal class '.vImp' with 2 slots
      • @Variables: chr [1:7]
      • @vImp: 'data.frame': 7 bs. of 3 variables:
        • $variables:Factor w/ 7 levels
          • $Ctest: num [1:7]
          • $Atest: num [1:7]

In total there are 400 classes of '.vImp' which are all in the same format. What I am attempting to do is extract the '@vImp: data. frame' for each class and merge them into a new dataframe. I able am to do this individually with the following line:

vic = as.data.frame(vi2@vImplist$'1'@vImp) 

This produces the data.frame with the correct information for that class. However when I try performing this for all 400 classes at once, it fails.

vic = as.data.frame(vi2@vImplist$'1:400'@vImp) 

Error in as.data.frame(vi2@vImplist$'1:400'@vImp): trying to get slot "vImp" from an object of a basic class ("NULL") with no slots.

I also tried using a loop to complete the task. However, this also failed with the same error:

for (i in seq(from = 1, to = 1, by = 1)) {
vic = as.data.frame(vi2@vImplist$'[i]'@vImp)
output <- rbind(newdf,vic)
}  

Does anyone have any suggestions for what the problem might be?

According to the given information, vImplist is a list with 400 entries, so you want to access every of this entry. The entries have the names '1' , ..., '400' . Therefore, your code vic = as.data.frame(vi2@vImplist$'1'@vImp) works. You references the list entry by its name ( '1' is a character). When you use '1:400' or '[i]' , this is also interpreted as a name due to '' . Because these data.frames don't exist, NULL is returned, from which it is tried to retrieve the slot "vImp". This explains your error message.

You need to iterate over all entries of the list. The easiest way is to do this with lapply which operates on every entry of the list and you can retrieve the correct slot:

vic <- lapply(vi2@vImplist, function(x) {
  as.data.frame(x@vImp)
})

vic is now a list of data.frames. If you use rbind with do.call , you can directly use the list of data.frames as the input arguments, as do.call accepts a list of arguments:

output <- do.call("rbind", vic)

Edit

As @Rui Barradas pointed out, vImp is already a data.frame, so you don't need as.data.frame . Also, you can directly access the slots with slot and use the name of the accessed slot as a further argument to the function:

vic <- lapply(vi2@vImplist, slot, 'vImp') 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM