TransWikia.com

Remove NAs from nested list data frame

Stack Overflow Asked on December 25, 2021

The following really seems to be a tough nut to crack:

I have a data frame with a nested list:

df <- structure(list(zerobonds = c(1, 1, NA), nominal = c(20, 20, NA
), calls = list(list(c(NA, -1), 1), list(list(NA, -1), 1), NA), 
call_strike = list(list(c(NA, 90), 110), list(list(NA, 90), 
                                              110), NA), puts = list(NA, NA, list(c(NA, 1), -1)), put_strike = list(
                                                NA, NA, list(c(NA, 110), 90))), row.names = c(NA, -3L
                                                ), class = "data.frame")
df
##   zerobonds nominal     calls call_strike      puts  put_strike
## 1         1      20 NA, -1, 1 NA, 90, 110        NA          NA
## 2         1      20 NA, -1, 1 NA, 90, 110        NA          NA
## 3        NA      NA        NA          NA NA, 1, -1 NA, 110, 90

I want to print the structure without any NAs (dots instead of the blanks are ok too):

  zerobonds nominal calls call_strike  puts put_strike
1         1      20 -1, 1     90, 110                 
2         1      20 -1, 1     90, 110                 
3                                     1, -1    110, 90

I have tried all kinds of things, the best approach so far seems to be something like rapply(df, na.omit, how = "replace") where I can’t even suppress the Warnings (suppressWarnings doesn’t seem to work here!). print(df, na.print = "") doesn’t help either.

I am really exhausted now, nothing seems to work… data frames in the form of nested lists doesn’t seem to be a good idea after all… could anybody help?

2 Answers

You can try the code below

df[]<-rapply(Map(as.list,df), na.omit, how = "replace")

which gives

> df
  zerobonds nominal calls call_strike  puts put_strike
1         1      20 -1, 1     90, 110
2         1      20 -1, 1     90, 110
3                                     1, -1    110, 90

Answered by ThomasIsCoding on December 25, 2021

You can create your own recursive function and apply it to each column :

rm_nested_na <- function(x) {
  if (is.atomic(x)) {
    na.omit(x)
  } else {
    lapply(x, rm_nested_na)
  }
}

res <- df
listcol <- sapply(res, is.list)
res[listcol] <- lapply(res[listcol], rm_nested_na)

res

This is clearly inefficient if the nesting is deep.

Answered by py_b on December 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP