## Original data
D <- structure(list(grandparent = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "Grandma", class = "factor"), parent = structure(c(1L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 2L, 2L, 2L, 2L), .Label = c("", "Dave", "John", Mary"), class = "factor"), child = structure(c(1L, 1L, 5L, 6L, 1L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 1L, 4L, 2L, 3L), .Label = c("", Dana", "Daniel", "Doloris", "Jessica", "Joanne", "Max", Millie"), class = "factor"), grandchild = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 4L, 3L, 2L, 7L, 6L, 5L, 1L, 1L, 1L, 1L), .Label = c("", "Karl", "Kate", "Ken", "Pam", "Pat", "Peter"), class = "factor"), age = c(100L, 72L, 41L, 35L, 70L, 39L, 12L, 19L, 8L, 2L, 11L, 24L, 66L, 32L, 23L, 13L)), .Names = c("grandparent", parent", "child", "grandchild", "age"), class = "data.frame", row.names = c(NA, 16L))



    library(rjson)
    library(data.table)
    DT <- data.table(D)  # assuming `D` is your original data.frame



    rList <- list()
    parent <- list()
    child <- list()
    grandchild <- list()

    j <- 1
    while (j < nrow(DT)) {
      lastj <- j

      while (DT[j, parent=="" && grandparent != ""]) {
        rList[[length(rList)+1]] <- as.list(DT[j, list(name=grandparent, age)])
        j <- j+1
      }

      while (DT[j, child==""] && DT[(j-1):j, identical(grandparent[[1]], grandparent[[2]])]  && (j < nrow(DT)) ) {
        parent[[length(parent)+1]] <- as.list(DT[j, list(name=parent, age)])
        j <- j+1
      }

      while(DT[j, grandchild==""] && DT[(j-1):j, identical(parent[[1]], parent[[2]])]  && (j < nrow(DT)) ) {
        child[[length(child)+1]] <- as.list(DT[j, list(name=child, age)])
        j <- j+1
      }

      while(DT[j, grandchild!="" ] && DT[(j-1):j, identical(child[[1]], child[[2]])]  && (j < nrow(DT)) ) {
        grandchild[[length(grandchild)+1]] <- as.list(DT[j, list(name=grandchild, age)])
        j <- j+1
      }

      if (length(grandchild)) {
        child[[length(child)]][["children"]] <- grandchild
    #    grandchild <- list() # reset
      }
      if (length(child)) {
        parent[[length(parent)]][["children"]] <- child
    #    child <- list()
      }
      if (length(parent)) {
        rList[[length(rList)]][["children"]] <- parent
    #    parent <- list()
      }

      cat ("\tat end, j  = ", j, "\n")

      # if j wasn't incremented throughout the whole loop, do so now. (This will happen when there is a change in the penultimate level)
      if (j == lastj)
        j <- j+1

    }

    RESULTS <- toJSON(rList)


    [
    {"name":"Grandma","age":100,"children":[
    {"name":"John","age":72,"children":[
    {"name":"Jessica","age":41},
    {"name":"Joanne","age":35}]},
    {"name":"Mary","age":70,"children":[
    {"name":"Jessica","age":41},
    {"name":"Joanne","age":35},
    {"name":"Max","age":39,"children":[
    {"name":"Ken","age":12},
    {"name":"Kate","age":19},
    {"name":"Karl","age":8},
    {"name":"Pat","age":11},
    {"name":"Pam","age":24}]}]},
    {"name":"Dave","age":66,"children":[
    {"name":"Jessica","age":41},
    {"name":"Joanne","age":35},
    {"name":"Max","age":39,"children":[
    {"name":"Ken","age":12},
    {"name":"Kate","age":19},
    {"name":"Karl","age":8},
    {"name":"Pat","age":11},
    {"name":"Pam","age":24}]},
    {"name":"Doloris","age":32},
    {"name":"Dana","age":23,"children":[
    {"name":"Ken","age":12},
    {"name":"Kate","age":19},
    {"name":"Karl","age":8},
    {"name":"Pat","age":11},
    {"name":"Pam","age":24}]}]}]}]
