1

I am working with jsonlite package in R and want to convert a complex list to JSON object. assume that x is my list:

library(jsonlite)
x= list(a=1,B=2,c=list(D=4,e=5,'F g'='NAME',H=list(i=list(j=list(K=1)))))

x=
$a
[1] 1

$B
[1] 2

$c
$c$D
[1] 4

$c$e
[1] 5

$c$`F g`
[1] "NAME"

$c$H
$c$H$i
$c$H$i$j
$c$H$i$j$K
[1] 1

toJSON(x)
{"a":[1],"B":[2],"c":{"D":[4],"e":[5],"F g":["NAME"],"H":{"i":{"j":{"K":[1]}}}}} 

how can I remove any special case in the JSON keys (like space between F and g as well as lower casing all keys?

I know one option is to operate on the list before feeding into the toJSON() function but even in that case, I have no ideas of how to rename all elements of a list (in particular my list contains some data.frames as well). Is there any regular expression method to do it?

MyQ
  • 459
  • 3
  • 13
  • Possible duplicate of [Rename list of lists using a named list](https://stackoverflow.com/questions/47770967/rename-list-of-lists-using-a-named-list) – acylam Mar 06 '19 at 16:34

1 Answers1

1

A recursive function to rename all the list of list elements should work. Here, it converts to lower case and also removes all non alpha-numeric characters (spaces, punctuation, etc)

x <- list(a=1,B=2,C=list(D=4,e=5,'F g'='NAME',H=list(i=list(j=list(K=1)))))
renames <- function(x)
{
  cnames <- names(x)
  if (is.null(cnames)) return (x)
  x1 <- lapply(cnames,function(y) renames(x[[y]]))
  if (class(x) %in% "data.frame") x1 <- as.data.frame(x1)
  names(x1) <- gsub("[^[:alnum:]]","",tolower(cnames))
  return(x1)
}

x1 <- renames(x)
> x1
$a
[1] 1

$b
[1] 2

$c
$c$d
[1] 4

$c$e
[1] 5

$c$fg
[1] "NAME"

$c$h
$c$h$i
$c$h$i$j
$c$h$i$j$k
[1] 1
Soren
  • 1,792
  • 1
  • 13
  • 16
  • Thanks@Soren but the function does not work properly. Just test this data: x <- list(a = 1, B = 2, C = list( D = 4, e = 5, 'F g' = 'NAME', H = list(i = list(j = list( K = 1, l = list(m = data.frame( a = 1:10, b = runif(10), "c d f g" = runif(10), check.rows = FALSE, check.names = FALSE )) ))) )) – MyQ Mar 06 '19 at 16:42
  • @MyQ I ran your new list -- first glance seems it did what was needed, although it returned all objects as a list rather than element 'm' as a formatted data frame. Formatting aside, it's all there. See for example "as.data.frame(x1$c$h$i$j$l$m)" which returns the object class and formatting. Is this what you mean by not working properly? What is your expectation in converting back and forth to JSON in terms of retaining object class information? – Soren Mar 06 '19 at 16:49
  • Thanks Soren. yes the issue is the that your code would manipulate the entire names in the data.frames that could be quite tricky to fix that – MyQ Mar 06 '19 at 16:50
  • Updated to cast as.data.frame when input object is a data frame, seems to resolve the issue? – Soren Mar 06 '19 at 16:52