如何处理 jsonlite 中的缺失值?
How to deal with missing values in jsonlite?
我正在处理来自重复测量设计的数据。数据由 4 个测量组成,每个测量大约 100 个变量。这些变量之一是包含反应任务结果的 JSON 数组。这个数组的结构基本上是这样的:[[素数,答案,反应时间],[素数,答案,反应时间],...]
每个数组包含大约 80 个试验。我的目标是将此数组转换为单独的列,使其看起来像下面的示例:
prime1 answer1 reaction_time1 prime2 answer2 reaction_time2 ...
picture8 2 2398 2 1 1856
picture8 1 798 1 2 712
...
在处理示例数据集时,我设法使用以下代码将数组转换为数据帧:
reaction_data <- data.frame(example_data$ID, example_data$TP,
jsonlite::stream_in(textConnection(gsub("\n", "", example_data$reaction_raw))))
如上所述,我现在正在处理以长格式排列的重复测量数据。因此,对于每个人 ID
我有四个测量值 TP
,理想情况下,所有 100 个变量的完整数据集,包括 JSON 数组。但是,实际上,我当然要处理辍学和缺失值。这意味着在某些情况下 JSON 数组也会丢失。假装我的 JSON-array 只包含 3 个试验,我当前的数据框看起来或多或少像下面的示例数据(忽略所有其他变量):
ID TP reaction_raw
1 1 [[picture8, 2, 2398], [picture2, 1, 1856], [picture1, 1, 897]]
1 2 [[picture8, 1, 798], [picture2, 2, 712], [picture1, 1, 423]]
1 3 NA
1 4 [[picture8, 1, 1278], [picture2, 1, 1712], [picture1, 1, 902]]
2 1 [[picture8, 2, 2015], [picture2, 1, 3820], [picture1, 2, 2719]]
2 2 [[picture8, 2, 3219], [picture2, 2, 1920], [picture1, 1, 1298]]
2 3 NA
2 4 NA
3 1 [[picture8, 1, 209], [picture2, 1, 382], [picture1, 2, 891]]
3 2 NA
3 3 [[picture8, 2, 781], [picture2, 1, 291], [picture1, 1, 2039]]
3 4 NA
...
当 运行 现在我的代码时,我收到以下错误消息:
lexical error: invalid char in json text.
NA
(right here) ------^
我想我的代码无法处理丢失的数组。有人知道如何处理这个问题吗?
提前致谢!
假设示例中缺少引号(否则解析器不会在没有抱怨的情况下通过 picture8
的第一次出现),处理此问题的方法是添加适当格式的 json 字符串,将转换为所需数据结构中的 NA
个条目。
因此,例如,假设您的数据如下所示:
df
#> # A tibble: 12 x 3
#> ID TP reaction_raw
#> <int> <int> <chr>
#> 1 1 1 "[[\"picture8\", 2, 2398], [\"picture2\", 1, 1856], [\"picture1\~
#> 2 1 2 "[[\"picture8\", 1, 798], [\"picture2\", 2, 712], [\"picture1\",~
#> 3 1 3 <NA>
#> 4 1 4 "[[\"picture8\", 1, 1278], [\"picture2\", 1, 1712], [\"picture1\~
#> 5 2 1 "[[\"picture8\", 2, 2015], [\"picture2\", 1, 3820], [\"picture1\~
#> 6 2 2 "[[\"picture8\", 2, 3219], [\"picture2\", 2, 1920], [\"picture1\~
#> 7 2 3 <NA>
#> 8 2 4 <NA>
#> 9 3 1 "[[\"picture8\", 1, 209], [\"picture2\", 1, 382], [\"picture1\",~
#> 10 3 2 <NA>
#> 11 3 3 "[[\"picture8\", 2, 781], [\"picture2\", 1, 291], [\"picture1\",~
#> 12 3 4 <NA>
然后你可以用 null
参数写一个 json 作为缺失值,然后写在 reaction_raw
是 NA
:
的地方
nulljson <- "[[\"picture8\", null, null],
[\"picture2\", null, null],
[\"picture1\", null, null]]"
df$reaction_raw[is.na(df$reaction_raw)] <- nulljson
现在您可以将 json 调整为单独的列...
parser <- function(x) as.vector(t(jsonlite::fromJSON(x)))
result_matrix <- do.call(rbind, lapply(df$reaction_raw, parser))
result_df <- as.data.frame(result_matrix)
col_names <- c("prime", "answer", "reaction_time")
col_names <- paste0(col_names, rep(1:3, each = ncol(result_df)/3))
result_df <- setNames(result_df,col_names)
...并将它们加入您的主数据框:
cbind(df[1:2], result_df)
#> ID TP prime1 answer1 reaction_time1 prime2 answer2 reaction_time2
#> 1 1 1 picture8 2 2398 picture2 1 1856
#> 2 1 2 picture8 1 798 picture2 2 712
#> 3 1 3 picture8 <NA> <NA> picture2 <NA> <NA>
#> 4 1 4 picture8 1 1278 picture2 1 1712
#> 5 2 1 picture8 2 2015 picture2 1 3820
#> 6 2 2 picture8 2 3219 picture2 2 1920
#> 7 2 3 picture8 <NA> <NA> picture2 <NA> <NA>
#> 8 2 4 picture8 <NA> <NA> picture2 <NA> <NA>
#> 9 3 1 picture8 1 209 picture2 1 382
#> 10 3 2 picture8 <NA> <NA> picture2 <NA> <NA>
#> 11 3 3 picture8 2 781 picture2 1 291
#> 12 3 4 picture8 <NA> <NA> picture2 <NA> <NA>
#> prime3 answer3 reaction_time3
#> 1 picture1 1 897
#> 2 picture1 1 423
#> 3 picture1 <NA> <NA>
#> 4 picture1 1 902
#> 5 picture1 2 2719
#> 6 picture1 1 1298
#> 7 picture1 <NA> <NA>
#> 8 picture1 <NA> <NA>
#> 9 picture1 2 891
#> 10 picture1 <NA> <NA>
#> 11 picture1 1 2039
#> 12 picture1 <NA> <NA>
使用的数据
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 3L), TP = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L
), reaction_raw = c(
"[[\"picture8\", 2, 2398], [\"picture2\", 1, 1856], [\"picture1\", 1, 897]]",
"[[\"picture8\", 1, 798], [\"picture2\", 2, 712], [\"picture1\", 1, 423]]",
NA, "[[\"picture8\", 1, 1278], [\"picture2\", 1, 1712], [\"picture1\", 1, 902]]",
"[[\"picture8\", 2, 2015], [\"picture2\", 1, 3820], [\"picture1\", 2, 2719]]",
"[[\"picture8\", 2, 3219], [\"picture2\", 2, 1920], [\"picture1\", 1, 1298]]",
NA, NA, "[[\"picture8\", 1, 209], [\"picture2\", 1, 382], [\"picture1\", 2, 891]]",
NA, "[[\"picture8\", 2, 781], [\"picture2\", 1, 291], [\"picture1\", 1, 2039]]",
NA)), row.names = c(NA, -12L), class = c("tbl_df", "tbl", "data.frame"
))
由 reprex package (v0.3.0)
于 2020-07-07 创建
我正在处理来自重复测量设计的数据。数据由 4 个测量组成,每个测量大约 100 个变量。这些变量之一是包含反应任务结果的 JSON 数组。这个数组的结构基本上是这样的:[[素数,答案,反应时间],[素数,答案,反应时间],...]
每个数组包含大约 80 个试验。我的目标是将此数组转换为单独的列,使其看起来像下面的示例:
prime1 answer1 reaction_time1 prime2 answer2 reaction_time2 ...
picture8 2 2398 2 1 1856
picture8 1 798 1 2 712
...
在处理示例数据集时,我设法使用以下代码将数组转换为数据帧:
reaction_data <- data.frame(example_data$ID, example_data$TP,
jsonlite::stream_in(textConnection(gsub("\n", "", example_data$reaction_raw))))
如上所述,我现在正在处理以长格式排列的重复测量数据。因此,对于每个人 ID
我有四个测量值 TP
,理想情况下,所有 100 个变量的完整数据集,包括 JSON 数组。但是,实际上,我当然要处理辍学和缺失值。这意味着在某些情况下 JSON 数组也会丢失。假装我的 JSON-array 只包含 3 个试验,我当前的数据框看起来或多或少像下面的示例数据(忽略所有其他变量):
ID TP reaction_raw
1 1 [[picture8, 2, 2398], [picture2, 1, 1856], [picture1, 1, 897]]
1 2 [[picture8, 1, 798], [picture2, 2, 712], [picture1, 1, 423]]
1 3 NA
1 4 [[picture8, 1, 1278], [picture2, 1, 1712], [picture1, 1, 902]]
2 1 [[picture8, 2, 2015], [picture2, 1, 3820], [picture1, 2, 2719]]
2 2 [[picture8, 2, 3219], [picture2, 2, 1920], [picture1, 1, 1298]]
2 3 NA
2 4 NA
3 1 [[picture8, 1, 209], [picture2, 1, 382], [picture1, 2, 891]]
3 2 NA
3 3 [[picture8, 2, 781], [picture2, 1, 291], [picture1, 1, 2039]]
3 4 NA
...
当 运行 现在我的代码时,我收到以下错误消息:
lexical error: invalid char in json text.
NA
(right here) ------^
我想我的代码无法处理丢失的数组。有人知道如何处理这个问题吗? 提前致谢!
假设示例中缺少引号(否则解析器不会在没有抱怨的情况下通过 picture8
的第一次出现),处理此问题的方法是添加适当格式的 json 字符串,将转换为所需数据结构中的 NA
个条目。
因此,例如,假设您的数据如下所示:
df
#> # A tibble: 12 x 3
#> ID TP reaction_raw
#> <int> <int> <chr>
#> 1 1 1 "[[\"picture8\", 2, 2398], [\"picture2\", 1, 1856], [\"picture1\~
#> 2 1 2 "[[\"picture8\", 1, 798], [\"picture2\", 2, 712], [\"picture1\",~
#> 3 1 3 <NA>
#> 4 1 4 "[[\"picture8\", 1, 1278], [\"picture2\", 1, 1712], [\"picture1\~
#> 5 2 1 "[[\"picture8\", 2, 2015], [\"picture2\", 1, 3820], [\"picture1\~
#> 6 2 2 "[[\"picture8\", 2, 3219], [\"picture2\", 2, 1920], [\"picture1\~
#> 7 2 3 <NA>
#> 8 2 4 <NA>
#> 9 3 1 "[[\"picture8\", 1, 209], [\"picture2\", 1, 382], [\"picture1\",~
#> 10 3 2 <NA>
#> 11 3 3 "[[\"picture8\", 2, 781], [\"picture2\", 1, 291], [\"picture1\",~
#> 12 3 4 <NA>
然后你可以用 null
参数写一个 json 作为缺失值,然后写在 reaction_raw
是 NA
:
nulljson <- "[[\"picture8\", null, null],
[\"picture2\", null, null],
[\"picture1\", null, null]]"
df$reaction_raw[is.na(df$reaction_raw)] <- nulljson
现在您可以将 json 调整为单独的列...
parser <- function(x) as.vector(t(jsonlite::fromJSON(x)))
result_matrix <- do.call(rbind, lapply(df$reaction_raw, parser))
result_df <- as.data.frame(result_matrix)
col_names <- c("prime", "answer", "reaction_time")
col_names <- paste0(col_names, rep(1:3, each = ncol(result_df)/3))
result_df <- setNames(result_df,col_names)
...并将它们加入您的主数据框:
cbind(df[1:2], result_df)
#> ID TP prime1 answer1 reaction_time1 prime2 answer2 reaction_time2
#> 1 1 1 picture8 2 2398 picture2 1 1856
#> 2 1 2 picture8 1 798 picture2 2 712
#> 3 1 3 picture8 <NA> <NA> picture2 <NA> <NA>
#> 4 1 4 picture8 1 1278 picture2 1 1712
#> 5 2 1 picture8 2 2015 picture2 1 3820
#> 6 2 2 picture8 2 3219 picture2 2 1920
#> 7 2 3 picture8 <NA> <NA> picture2 <NA> <NA>
#> 8 2 4 picture8 <NA> <NA> picture2 <NA> <NA>
#> 9 3 1 picture8 1 209 picture2 1 382
#> 10 3 2 picture8 <NA> <NA> picture2 <NA> <NA>
#> 11 3 3 picture8 2 781 picture2 1 291
#> 12 3 4 picture8 <NA> <NA> picture2 <NA> <NA>
#> prime3 answer3 reaction_time3
#> 1 picture1 1 897
#> 2 picture1 1 423
#> 3 picture1 <NA> <NA>
#> 4 picture1 1 902
#> 5 picture1 2 2719
#> 6 picture1 1 1298
#> 7 picture1 <NA> <NA>
#> 8 picture1 <NA> <NA>
#> 9 picture1 2 891
#> 10 picture1 <NA> <NA>
#> 11 picture1 1 2039
#> 12 picture1 <NA> <NA>
使用的数据
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 3L), TP = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L
), reaction_raw = c(
"[[\"picture8\", 2, 2398], [\"picture2\", 1, 1856], [\"picture1\", 1, 897]]",
"[[\"picture8\", 1, 798], [\"picture2\", 2, 712], [\"picture1\", 1, 423]]",
NA, "[[\"picture8\", 1, 1278], [\"picture2\", 1, 1712], [\"picture1\", 1, 902]]",
"[[\"picture8\", 2, 2015], [\"picture2\", 1, 3820], [\"picture1\", 2, 2719]]",
"[[\"picture8\", 2, 3219], [\"picture2\", 2, 1920], [\"picture1\", 1, 1298]]",
NA, NA, "[[\"picture8\", 1, 209], [\"picture2\", 1, 382], [\"picture1\", 2, 891]]",
NA, "[[\"picture8\", 2, 781], [\"picture2\", 1, 291], [\"picture1\", 1, 2039]]",
NA)), row.names = c(NA, -12L), class = c("tbl_df", "tbl", "data.frame"
))
由 reprex package (v0.3.0)
于 2020-07-07 创建