2017-12-06 9 views
0

CSVファイルの列であるJSONデータを抽出しようとしています。これまでのところ、適切な形式で列を抽出したところにきましたが、変数の型が要素である場合にのみ書式設定が正しく行われます。しかし、jsonliteパッケージを使用して因子をjson-fileに変換することはできません。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ファイルの小さな例:

"","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}から来ている行を失い、{「」X "":197、 "" y "::135}]'私はまだ行4をスペアする必要があります。 –

+0

これで、私の答えは修正されました。あなたは期待どおり* 5つではなく、6行を取得する必要があります*。 –

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からの情報をデータフレームに抽出することです。

ロード必要なパッケージと次にリストに各JSONを変換しUnloadVars列に入れ

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

unvalid JSONを削除したデータに

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

をお読みください。あなたがそれを知らなかったら、データフレームのリスト列を持つことが可能です。これは非常に便利です。

Unload VarsのリストからIDを抽出できるようになりました。リストあたりIDが1つしかないため、これは簡単です。

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

この最終的な部分は少し威圧するようです。しかし、私がここでやっているのは、UnloadVars列のインタラクション部分をinteraction列に入れることです。次に、各行をリストであるinteractionから、keyvalueの2つの列を持つデータフレームに変換します。 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、私はそれを追加することを忘れました。私が書いたカスタム機能でした。それに気づいてくれてありがとう –

関連する問題