解析类似字典的结构,其中键和值是使用R的数值

解析类似字典的结构,其中键和值是使用R的数值,r,dictionary,jsonlite,R,Dictionary,Jsonlite,我试图解析我在旅行中遇到的一些奇怪的数据结构。本质上,它们类似于python或javascript字典,但键和值都是数字: weird <- "{47=4578.0005, 181=23456.7831, 216=7548.2367}" parse_json函数正确地抱怨键不是字符串。我当然可以使用str_split剖析所有这些,但我希望善良的灵魂能够洞察到一种更优雅/紧凑的解决方案(希望完全避免使用正则表达式),从而将其解析为一个表: tibble::tribble( ~ key,

我试图解析我在旅行中遇到的一些奇怪的数据结构。本质上,它们类似于python或javascript字典,但键和值都是数字:

weird <- "{47=4578.0005, 181=23456.7831, 216=7548.2367}"
parse_json
函数正确地抱怨键不是字符串。我当然可以使用
str_split
剖析所有这些,但我希望善良的灵魂能够洞察到一种更优雅/紧凑的解决方案(希望完全避免使用正则表达式),从而将其解析为一个表:

tibble::tribble(
  ~ key,    ~ value,
  47,  4578.0005,
  181, 23456.7831,
  216,  7548.2367 
)
#> # A tibble: 3 x 2
#>     key  value
#>   <dbl>  <dbl>
#> 1    47  4578.
#> 2   181 23457.
#> 3   216  7548.
tibble::tribble(
~key,~value,
47,  4578.0005,
181, 23456.7831,
216,  7548.2367 
)
#>#tibble:3 x 2
#>关键值
#>     
#> 1    47  4578.
#> 2   181 23457.
#> 3   216  7548.

谢谢

JSON要求引用其字典键。虽然此解决方案还引用了值,但(如果您确定数据集)将
作为.numeric
应用于值应该不难

库(dplyr)
图书馆(tidyr)
gsub(“=”,“:”,gsub(\\b |-?)([0-9.]+)\\b“,“\\1”,奇怪))%>%
jsonlite::fromJSON(.)%>%
enframe()%>%
unnest(值)
##tibble:3 x 2
#名称值
#         
# 1 47    4578.0005 
# 2 181   23456.7831
# 3 216   7548.2367 
这假设所有键和值都是完全数字的(可能是负数,也可能是十进制),但在这种模式中没有科学的表示法。这不是不可能的,所以如果你需要更进一步,也许会有所帮助

下一步可能很简单

gsub(“=”,“:”,gsub(\\b |-?)([0-9.]+)\\b“,“\\1”,奇怪))%>%
jsonlite::fromJSON(.)%>%
enframe()%>%
unnest(值)%%>%
全部变异(如数字)
##tibble:3 x 2
#名称值
#     
# 1    47  4578.
# 2   181 23457.
# 3   216  7548.

(小数点的明显丢失只是一种表示方式,原始数据仍然具有非整数值。)

JSON要求引用其字典键。虽然此解决方案还引用了值,但(如果您确定数据集)将
作为.numeric
应用于值应该不难

库(dplyr)
图书馆(tidyr)
gsub(“=”,“:”,gsub(\\b |-?)([0-9.]+)\\b“,“\\1”,奇怪))%>%
jsonlite::fromJSON(.)%>%
enframe()%>%
unnest(值)
##tibble:3 x 2
#名称值
#         
# 1 47    4578.0005 
# 2 181   23456.7831
# 3 216   7548.2367 
这假设所有键和值都是完全数字的(可能是负数,也可能是十进制),但在这种模式中没有科学的表示法。这不是不可能的,所以如果你需要更进一步,也许会有所帮助

下一步可能很简单

gsub(“=”,“:”,gsub(\\b |-?)([0-9.]+)\\b“,“\\1”,奇怪))%>%
jsonlite::fromJSON(.)%>%
enframe()%>%
unnest(值)%%>%
全部变异(如数字)
##tibble:3 x 2
#名称值
#     
# 1    47  4578.
# 2   181 23457.
# 3   216  7548.

(小数点的明显丢失只是一种表示方式,原始数据仍然具有非整数值。)

虽然您可能需要一个紧凑的非正则版本,但这似乎是我最容易理解和理解的:

库(stringr)
图书馆(dplyr)
奇怪的%
str_split(“,”,simplify=TRUE)%>%
str_split(“=”,simplify=TRUE)%>%
as_tible()%>%
全部变异(如数字)
#>#tibble:3 x 2
#>V1 V2
#>     
#> 1    47  4578.
#> 2   181 23457.
#> 3   216  7548.
由(v0.3.0)于2020年4月20日创建


我不介意对数据进行三次传递,每一步只完成一件事。我发现它更容易阅读和推理。

虽然您可能想要一个紧凑的非正则版本,但这似乎是我最容易理解和理解的:

库(stringr)
图书馆(dplyr)
奇怪的%
str_split(“,”,simplify=TRUE)%>%
str_split(“=”,simplify=TRUE)%>%
as_tible()%>%
全部变异(如数字)
#>#tibble:3 x 2
#>V1 V2
#>     
#> 1    47  4578.
#> 2   181 23457.
#> 3   216  7548.
由(v0.3.0)于2020年4月20日创建


我不介意对数据进行三次传递,每一步只完成一件事。我发现它更容易阅读和推理。

我不认为您可以完全避免使用正则表达式,但通过一些小的替换,它可以通过
read.table()
轻松阅读


wt我不认为您可以完全避免使用正则表达式,但是通过
read.table()


wt当数据不总是数字时,这可能比
jsonlite
方法更健壮,假设(当然)没有嵌入/转义的逗号或等号。我梦想的方法类似于
parse(text=glue(“list({weird})”)
但不幸的是,R中的列表名也不能是纯数字。当数据不总是数字时,如果(当然)没有嵌入/转义的逗号或等号,这可能比
jsonlite
方法更健壮。我梦想的方法类似于
parse(text=glue(“list({weird})”
但不幸的是,R中的列表名称也不能是空的数字。这非常有用,我特别喜欢
enframe
函数,这是一个我一定会记得的小宝石!当我最初发布问题时,我立即翻倍并编辑了我的问题,指定我希望避免使用正则表达式。我想你发布了你的问题r asnwer在那些编辑完成之前,所以你完美地回答了我未经编辑的问题。然而,我怀疑像许多用户一样,我倾向于尽可能避免使用正则表达式,因为它的复杂性令人望而生畏。好的,我理解。Brian的答案最接近于没有正则表达式,尽管需要替换所有的
str\u remove\u
{}
,您需要
substr
,但它会盲目地这样做,而不管t
tibble::tribble(
  ~ key,    ~ value,
  47,  4578.0005,
  181, 23456.7831,
  216,  7548.2367 
)
#> # A tibble: 3 x 2
#>     key  value
#>   <dbl>  <dbl>
#> 1    47  4578.
#> 2   181 23457.
#> 3   216  7548.
wt <- c("{47=4578.0005, 181=23456.7831, 216=7548.2367}")

read.table(text = gsub("[{},]", "\n", wt), sep = "=")

   V1        V2
1  47  4578.001
2 181 23456.783
3 216  7548.237