2017-12-06 1 views
0

CSV 파일의 열인 JSON 데이터를 추출하려고합니다. 지금까지 올바른 형식으로 열을 추출한 지점으로 왔지만 변수 형식이 요소 일 때만 형식이 올바른 것입니다. 하지만 jsonlite 패키지를 사용하여 요인을 json 파일로 변환 할 수는 없습니다.CSV 파일에서 JSON 데이터 추출

[1] {"id":509746197991998767,"visibility":{"percentage":100,"time":149797,"visible1":true,"visible2":false,"visible3":false,"activetab":true},"interaction":{"mouseovercount":1,"mouseovertime":1426,"videoplaytime":0,"engagementtime":0,"expandtime":0,"exposuretime":35192}} 

또 다른 방법은 가져올 때 stringsAsFactors = F를 사용하는 것입니다,하지만 난 각 항목은 다음과 같습니다 곳에 서식 권리를 얻기에 어려움을 겪고있어 :

[1] "{\"id\":509746197991998767,\"visibility\":{\"percentage\":100,\"time\":149797,\"visible1\":true,\"visible2\":false,\"visible3\":false,\"activetab\":true},\"interaction\":{\"mouseovercount\":1,\"mouseovertime\":1426,\"videoplaytime\":0,\"engagementtime\":0,\"expandtime\":0,\"exposuretime\":35192}}" 

내가 여기서 뭔가를 분명 실종? CSV 파일 안에있는 JSON 개의 파일을 추출하기 만하면됩니다. CSV 파일의 Heres는 작은 예를

:

"","CookieID","UnloadVars" 
"1",-8857188784608690176,"{""id"":509746197991998767,""visibility"":{""percentage"":100,""time"":149797,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":1,""mouseovertime"":1426,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":35192}}" 
"2",-1695626857458244096,"{""id"":2917654329769114342,""visibility"":{""percentage"":46,""time"":0,""visible1"":false,""visible2"":false,""visible3"":false,""activetab"":true}}" 
"3",437299165071669184,"{""id"":2252707957388071809,""visibility"":{""percentage"":99,""time"":10168,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":0,""mouseovertime"":0,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":542},""clicks"":[{""x"":105,""y"":449}]}" 
"4",292660729552227520,"" 
"5",7036383942916227072,"{""id"":2299674593327687292,""visibility"":{""percentage"":76,""time"":1145,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":0,""mouseovertime"":0,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":74},""clicks"":[{""x"":197,""y"":135},{""x"":197,""y"":135}]}" 

감사합니다,

프레데릭.

+0

는 CSV의 샘플을 제공하십시오. – Taran

+0

아, 고마워. 원래 질문에 작은 샘플을 추가했습니다. – user2447806

답변

1
df <- readr::read_csv('"","CookieID","UnloadVars" 
"1",-8857188784608690176,"{""id"":509746197991998767,""visibility"":{""percentage"":100,""time"":149797,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":1,""mouseovertime"":1426,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":35192}}" 
"2",-1695626857458244096,"{""id"":2917654329769114342,""visibility"":{""percentage"":46,""time"":0,""visible1"":false,""visible2"":false,""visible3"":false,""activetab"":true}}" 
"3",437299165071669184,"{""id"":2252707957388071809,""visibility"":{""percentage"":99,""time"":10168,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":0,""mouseovertime"":0,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":542},""clicks"":[{""x"":105,""y"":449}]}" 
"4",292660729552227520,"" 
"5",7036383942916227072,"{""id"":2299674593327687292,""visibility"":{""percentage"":76,""time"":1145,""visible1"":true,""visible2"":false,""visible3"":false,""activetab"":true},""interaction"":{""mouseovercount"":0,""mouseovertime"":0,""videoplaytime"":0,""engagementtime"":0,""expandtime"":0,""exposuretime"":74},""clicks"":[{""x"":197,""y"":135},{""x"":197,""y"":135}]}"', 
col_types = "-cc") 

tidyr::unnest

library(dplyr) 

f <- function(.x) 
    if (is.na(.x) || .x == "") data.frame()[1, ] else 
    as.data.frame(jsonlite::fromJSON(.x)) 

df %>% 
    tidyr::unnest(UnloadVars = lapply(UnloadVars, f)) %>% 
    mutate_at(vars(ends_with("id")), as.character) 

# A tibble: 6 x 16 
#    CookieID     id visibility.percentage visibility.time visibility.visible1 visibility.visible2 visibility.visible3 visibility.activetab interaction.mouseovercount interaction.mouseovertime interaction.videoplaytime interaction.engagementtime interaction.expandtime interaction.exposuretime clicks.x clicks.y 
#     <chr>    <chr>     <int>   <int>    <lgl>    <lgl>    <lgl>    <lgl>      <int>      <int>      <int>      <int>     <int>     <int> <int> <int> 
# 1 -8857188784608690176 509746197991998784     100   149797    TRUE    FALSE    FALSE     TRUE       1      1426       0       0      0     35192  NA  NA 
# 2 -1695626857458244096 2917654329769114112     46    0    FALSE    FALSE    FALSE     TRUE       NA      NA      NA       NA      NA      NA  NA  NA 
# 3 437299165071669184 2252707957388071936     99   10168    TRUE    FALSE    FALSE     TRUE       0       0       0       0      0      542  105  449 
# 4 292660729552227520    <NA>     NA    NA     NA     NA     NA     NA       NA      NA      NA       NA      NA      NA  NA  NA 
# 5 7036383942916227072 2299674593327687168     76   1145    TRUE    FALSE    FALSE     TRUE       0       0       0       0      0      74  197  135 
# 6 7036383942916227072 2299674593327687168     76   1145    TRUE    FALSE    FALSE     TRUE       0       0       0       0      0      74  197  135 
+0

Oups. 나는 잘못한 것을했고 어떻게 든 행 5를 행 4에 복사했습니다. 매우 이상합니다. 아직 사용하지 마십시오. –

+0

* 편집 : 실제로 행하지는 않았지만 행 4를 잃어 버렸습니다. 마지막 행의 중복은 마지막 배열'{{ ""x "": 197, "y" ": 135}, { "": 197 ","y "": 135}]'. 나는 여전히 행 4를 예비해야한다. –

+0

좋아, 이제 대답을 수정했다. 예상대로 6 개 행을 가져오고 5 개가 아닌 *를 얻어야합니다. –

0

샘플 데이터 세트를 읽는 데 readr :: read_csv를 사용했습니다.

> df <- readr::read_csv('~/sample.csv') 
Parsed with column specification: 
cols(
    CookieID = col_double(), 
    UnloadVars = col_character() 
) 

위에서 볼 수 있듯이 UnloadVars는 문자가 아닌 인자로 읽습니다. 지금은 지금은 당신이 무엇을 얻을 일치 다음을 참조 UnloadVars 열에서 첫 번째 값,

> df$UnloadVars[1] 
[1] "{\"id\":509746197991998767,\"visibility\":{\"percentage\":100,\"time\":149797,\"visible1\":true,\"visible2\":false,\"visible3\":false,\"activetab\":true},\"interaction\":{\"mouseovercount\":1,\"mouseovertime\":1426,\"videoplaytime\":0,\"engagementtime\":0,\"expandtime\":0,\"exposuretime\":35192}}" 

을 살펴보면, 나는 jsonlite :: fromJSON을, 저는 믿습니다

> j <- jsonlite::fromJSON(df$UnloadVars[1]) 
> j 
$id 
[1] 5.097462e+17 

$visibility 
$visibility$percentage 
[1] 100 

$visibility$time 
[1] 149797 

$visibility$visible1 
[1] TRUE 

$visibility$visible2 
[1] FALSE 

$visibility$visible3 
[1] FALSE 

$visibility$activetab 
[1] TRUE 


$interaction 
$interaction$mouseovercount 
[1] 1 

$interaction$mouseovertime 
[1] 1426 

$interaction$videoplaytime 
[1] 0 

$interaction$engagementtime 
[1] 0 

$interaction$expandtime 
[1] 0 

$interaction$exposuretime 
[1] 35192 

입니다 무엇을 사용하면 JSON은 R의 목록으로 파싱되기 때문에 필요합니다.

+0

아 물론. 고마워. 나는 [1]로 결과를 입력하는 것을 잊었다. 하지만 지금은 내 CSV 파일에서 이해할 수있는 구문 분석 된 JSON이 붙어 있습니다. 원래 데이터 프레임 (csv)에 항목을 추가하려고합니다 (예 : id). 어떻게해야합니까? – user2447806

+0

df에서 열로 설정하려는 JSON의 특정 구성 요소가 있습니까? – Taran

0

JSON 데이터를 처리하는 것은 매우 까다로운 작업 일 수 있습니다. 일반적인 가이드 라인으로, 항상 데이터 프레임에 데이터를 갖도록 노력해야합니다. 그러나 이것이 항상 가능하지는 않습니다. 특정 경우에는 형식이 올바른 데이터 프레임에서 한 번에 visibilityinteraction 값을 모두 가질 수있는 방법이 표시되지 않습니다.

다음은 데이터 프레임에 interaction의 정보를 추출하는 것입니다.

로드 필요한 패키지와 판독 된 데이터

library(purrr) 
library(dplyr) 
library(tidyr) 
df <- read.csv("sample.csv", stringsAsFactors = FALSE) 

이어서리스트로 각각 변환 unvalid JSON JSON에게

# remove rows without JSON (in this case, the 4th row) 
df <- df %>% 
    dplyr::filter(UnloadVars != "") 

제거하고 UnloadVars 컬럼에 넣어. 그 사실을 모르는 경우 데이터 프레임에 목록 열을 포함시킬 수 있습니다. 이것은 매우 유용 할 수 있습니다.

Unload Vars의 목록에서 ID를 추출 할 수 있습니다. 목록 당 하나의 ID 만 있기 때문에 이것은 간단합니다.

out <- out %>% 
    mutate(id = map_chr(UnloadVars, ~ .$id)) 

이 마지막 부분은 약간 위협적으로 보일 수 있습니다.그러나 여기서 내가하는 일은 상호 작용 부분을 UnloadVars 열에서 interaction 열로 바꾸는 것입니다. 그런 다음 각 행을 목록 인 interaction에서 keyvalue의 두 열이있는 데이터 프레임으로 변환합니다. key에는 상호 작용 측정 항목의 이름과 value 값이 포함되어 있습니다. 마침내 중첩되지 않아 목록 열을 없애고 멋지게 형식화 된 데이터 프레임을 만들게됩니다.

unpack_list <- function(obj, key_name) { 
    as.data.frame(obj) %>% 
    gather(key) %>% 
    return() 
} 

df_interaction <- out %>% 
    mutate(interaction = map(UnloadVars, ~ .$interaction)) %>% 
    mutate(interaction = map(interaction, ~ unpack_list(.x, key))) %>% 
    unnest(interaction) 

df_interaction 

해결책은 매우 우아하지 않지만 작업이 완료됩니다. 동일한 논리를 적용하여 가시성에서 정보를 추출 할 수 있습니다. 각각 별도의 값에 jsonlite::fromJSON을 사용

+0

'unpack_list '란 무엇입니까? –

+0

@ Aurèle, 나는 그것을 추가하는 것을 잊었다. 내가 작성한 커스텀 기능이었다. 주목 해 주셔서 감사합니다 –