【问题标题】:Extracting JSON-data from CSV file从 CSV 文件中提取 JSON 数据
【发布时间】:2018-05-20 10:14:49
【问题描述】:

我正在尝试提取 JSON 数据,它是 CSV 文件中的一列。到目前为止,我已经以正确的格式提取了列,但是仅当变量类型为因子时,格式才是正确的。但我无法使用 jsonlite 包将因子转换为 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}]}"

问候,

弗雷德里克。

【问题讨论】:

  • 请提供 csv 样本。
  • 啊,谢谢。我在原始问题中添加了一个小样本。

标签: json r csv


【解决方案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")

对每个单独的值使用jsonlite::fromJSON,然后使用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

【讨论】:

  • 欧普斯。我做错了什么,以某种方式将第 5 行复制到第 4 行。非常奇怪。暂时不要使用它。
  • 编辑: 实际上我没有,但我丢失了第 4 行。最后一行的重复来自最后一个数组 [{""x"":197,""y"":135},{""x"":197,""y"":135}]。我仍然需要保留第 4 行。
  • 好的,我现在已经确定了我的答案。您应该得到 6 行而不是 5 行,如预期的那样。
  • 哇。这是一个很好的解决方案。仍然没有经历并理解所有内容,但这里有很多东西要学。非常感谢!
【解决方案2】:

处理 JSON 数据可能非常棘手。作为一般指导方针,您应该始终努力将数据放在数据框中。然而,这并不总是可能的。在特定情况下,我看不出有一种方法可以在格式良好的数据框中同时拥有 visibility 和 interaction 值。

接下来我要做的是将interaction中的信息提取到一个数据框中。

加载所需的包并读取数据

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

然后删除无效的 JSON

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

将每个 JSON 转换为一个列表并将它们放入UnloadVars 列。如果您不知道,可以在数据框中有列表列。这可能非常有用。

out <- data_frame(CookieID = numeric(), 
                  UnloadVars = list())

for (row in 1:nrow(df)) {
  new_row <- data_frame(CookieID = df[row, ]$CookieID,
                        UnloadVars = list(jsonlite::fromJSON(df[row, ]$UnloadVars)))

  out <- bind_rows(out, new_row)
}

out

我们现在可以从 Unload Vars 的列表中提取 ID。这很简单,因为每个列表只有一个 ID。

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

这最后一部分看起来有点吓人。但我在这里所做的是从UnloadVars 列中获取交互部分并将其放入interaction 列中。然后,我将每一行从interaction(一个列表)转换为具有两列的数据框:key 和value。 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

解决方案不是很优雅,但可以完成工作。您可以应用相同的逻辑从可见性中提取信息。

【讨论】:

  • 什么是unpack_list?
  • @Aurèle,我忘了添加它。这是我编写的自定义函数。感谢您注意到
【解决方案3】:

我使用 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 中被解析为列表。

【讨论】:

  • 啊,当然。非常感谢。我忘了用 [1] 输入结果。但是现在我遇到了一个在我的 CSV 文件中可以理解的解析 JSON。我想将条目作为列添加到我的原始数据框(csv)中,例如 id。我该怎么做?
  • 您是否希望在 df 中将 JSON 的特定组件设置为列?
猜你喜欢
  • 2018-06-23
  • 2022-06-11
  • 2020-03-08
  • 2017-04-03
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多