2016-07-07 8 views
1

すっきりした整理済みのデータフレームを取得し、Rを使用して深くネストされたJSONに変換しようとしています。これまでは直接アドレス指定する他のリソースは見つかりませんでしたこのタスクは、ほとんどの場合、他の方向にそれを取ろうとしているようです(JSONのネスト解除)。データフレームから深くネストされたJSONをRに入れよう

私が始めているデータフレームの小さなダミーバージョンです。企業内の2人の聴衆(マネージャー用と従業員用)の調査があったとします。アンケートには異なるIDを使用したさまざまな質問がありますが、多くの質問は重複しており、2つのグループ間の回答を比較したいと思います。最終的な目標は、セクションID、質問ID、およびオプションID /テキストを2つのアンケートの正しい階層に収めたJSONを作成することです。いくつかの質問には、さらに難しいネスティングのレベルが必要なサブクエリがあります。

library(dplyr) 
library(tidyr) 
library(jsonlite) 

dummyDF <- data_frame(sectionId = c(rep(1,9),rep(2,3)), 
         questionId = c(rep(1,3),rep(2,6),rep(3,3)), 
         subquestionId = c(rep(NA,3),rep("2a",3),rep("2b",3),rep(NA,3)), 
         deptManagerQId = c(rep("m1",3),rep("m2",3),rep("m3",3),rep("m4",3)), 
         deptEmployeeQId = c(rep("e1",3),rep("e3",3),rep("e4",3),rep("e7",3)), 
         optionId = rep(c(1,2,3),4), 
         text = rep(c("yes","neutral","no"),4)) 

そして、ここで最終的な結果だ私が達成しようとしている:ここで

theGoal <- fromJSON('{ 
    "sections": [ 
    { 
     "sectionId": "1", 
     "questions": [ 
     { 
      "questionId": "1", 
      "deptManagerQId": "m1", 
      "deptEmployeeQId": "e1", 
      "options": [ 
      { 
       "optionId": 1, 
       "text": "yes" 
      }, 
      { 
       "optionId": 2, 
       "text": "neutral" 
      }, 
      { 
       "optionId": 3, 
       "text": "no" 
      } 
      ] 
     }, 
     { 
      "questionId": "2", 
      "options": [ 
      { 
       "optionId": 1, 
       "text": "yes" 
      }, 
      { 
       "optionId": 2, 
       "text": "neutral" 
      }, 
      { 
       "optionId": 3, 
       "text": "no" 
      } 
      ], 
      "subquestions": [ 
      { 
       "subquestionId": "2a", 
       "deptManagerQId": "m2", 
       "deptEmployeeQId": "e3" 
      }, 
      { 
       "subquestionId": "2b", 
       "deptManagerQId": "m3", 
       "deptEmployeeQId": "e4" 
      } 
      ] 
     }, 
     { 
      "questionId": "3", 
      "deptManagerQId": "m4", 
      "deptEmployeeQId": "e7", 
      "options": [ 
      { 
       "optionId": 1, 
       "text": "yes" 
      }, 
      { 
       "optionId": 2, 
       "text": "neutral" 
      }, 
      { 
       "optionId": 3, 
       "text": "no" 
      } 
      ] 
     } 
     ] 
    } 
    ] 
}') 

私が終わるtidyrから巣を使用して試したいくつかのアプローチは、どちらかだけ私の方法の一部を取得していますエラーメッセージが表示されます。

list2 <- dummyDF %>% nest(-sectionId, .key=questions) %>% 
    mutate(questions = lapply(seq_along(.$questions), 
          function(x) {ifelse(is.na(.$questions[[x]]$subquestionId), 
               function(x) {.$questions[[x]] %>% select(-subquestionId) %>% nest(optionId, text, .key = options)}, 
               function(x) {.$questions[[x]] %>% nest(subquestion_id, .key = subquestions)})})) %>% 
    list(sections = .) 
#Gives this error: attempt to replicate an object of type 'closure' 

任意のアイデア

nested1 <- dummyDF %>% nest(-sectionId, .key=questions) %>% 
    mutate(questions = lapply(seq_along(.$questions), function(x) nest(.$questions[[x]], optionId, text, .key = options))) 

nested2 <- nested1 %>% mutate(questions = lapply(seq_along(.$questions), function(x) nest(.$questions[[x]], subquestionId, .key = subquestions))) 
#Gives this error: cannot group column options, of class 'list' 
list1 <- dummyDF %>% nest(-sectionId, .key=questions) %>% 
    mutate(questions = lapply(seq_along(.$questions), function(x) nest(.$questions[[x]], optionId, text, .key = options))) %>% 
    list(sections = .) 

を大幅に理解されるであろう。私はどんなアプローチにも開放的です。私はこの問題をローカルのRユーザーグループのミーティングに持ち込んだが、解決策を考え出すことができなかったので、ここで私の指が交差してしまった。私はRがこれを達成するための最良のツールではないかもしれないことを理解していますが、私が知っているので、私はそれを撃っています。ありがとう。

+0

なぜ質問2に* deptManagerQId *と* deptEmployeeQId *が含まれていないのですか? – Parfait

+0

リーフの質問にはdeptManagerQIdとdeptEmployeeQIdが関連付けられています。質問2は、サーベイデータに直接関連付けられたレスポンスを持たない単なる親であり、子2aと2bを介してのみです。 – wes

答えて

0

jsonlite::toJSONは、あなたの問題に対する素晴らしい解決策のようです。

列の種類と列の順序までシームレスに動作します(オブジェクトが同一であることを示すために修正されました)。他のタイプのJSON構造が必要な場合は、dplyrまたはtidyrのようなものを使用して、フロントエンドでdata_frameを最初に再構築することをおすすめします。

library(jsonlite) 
library(dplyr) 

dummyDF <- data_frame(sectionId = c(rep(1,9),rep(2,3)), 
        questionId = c(rep(1,3),rep(2,6),rep(3,3)), 
        subquestionId = c(rep(NA,3),rep("2a",3),rep("2b",3),rep(NA,3)), 
        deptManagerQId = c(rep("m1",3),rep("m2",3),rep("m3",3),rep("m4",3)), 
        deptEmployeeQId = c(rep("e1",3),rep("e3",3),rep("e4",3),rep("e7",3)), 
        optionId = rep(c(1,2,3),4), 
        text = rep(c("yes","neutral","no"),4)) 

## Convert to a JSON object 
json <- jsonlite::toJSON(dummyDF) 


theGoal <- fromJSON(json) %>% tbl_df() %>% select_(.dots=names(dummyDF)) %>% 
    ## Convert integer columns to numeric 
    mutate_if(function(x) {if (typeof(x)=='integer') {TRUE} else {FALSE}},as.numeric) 

## Compare the objects 
all.equal(theGoal,dummyDF) 
# TRUE 

identical(theGoal,dummyDF) 
# TRUE 
関連する問題