Extract keys and values from hstore string in R

Viewed 94

I'm working in R with strings obtained from OpenStreetMap and stored using the hstore data type. For example:

"comment"=>"Removed junction=roundabout as some entrances have right of way. See http://wiki.openstreetmap.org/wiki/Tag:junction%3Droundabout","lit"=>"yes","maxspeed"=>"30 mph","oneway"=>"yes","surface"=>"asphalt"

I would like to create a regex (or any other approach is fine) to extract all keys and all values. Please notice that keys and values could contain the characters =, >, \", or ,. The ideal approach should use only functions implemented in base-R packages.

EDIT - Expected output

If the input is

"comment"=>"Removed junction=roundabout as some entrances have right of way. See http://wiki.openstreetmap.org/wiki/Tag:junction%3Droundabout","lit"=>"yes","maxspeed"=>"30 mph","oneway"=>"yes","surface"=>"asphalt"

then the expected output should be something like

keys: "comment", "lit", "maxspeed", "oneway", "surface"
values: "Removed junction=roundabout as some entrances have right of way. See http://wiki.openstreetmap.org/wiki/Tag:junction%3Droundabout", "yes", "30 mph", "yes", "asphalt"

If the input is

"lit"=>"no","foot"=>"designated","horse"=>"designated","bicycle"=>"yes","surface"=>"gravel","old_name"=>"Freshwater, Yarmouth & Newport Railway","prow_ref"=>"F61"

then the output should be like

keys: "lit", "foot", "horse", "bicycle", "surface", "old_name"
values: "no", "designated", "designated", "yes", "gravel", "Freshwater, Yarmouth & Newport"
2 Answers
  read.table(text=gsub(',?([^,]+)=>',"\n\\1:", string, perl = TRUE), sep=":", 
             col.names = c("Key", "value"))
       Key                                  value
1      lit                                     no
2     foot                             designated
3    horse                             designated
4  bicycle                                    yes
5  surface                                 gravel
6 old_name Freshwater, Yarmouth & Newport Railway
7 prow_ref                                    F61

We can use tidyverse approaches

library(dplyr)
library(tidyr)
library(stringr)
tibble(str1) %>% 
   separate_rows(str1, sep = '"[^"]+"(*SKIP)(*FAIL)|,') %>%
   separate(str1, into = c('key', 'value'), sep= '"=>"') %>%
   mutate(across(everything(), str_remove_all, pattern = '"'))

-output

# A tibble: 12 x 2
#   key      value                                                                                                                            
#   <chr>    <chr>                                                                                                                            
# 1 comment  Removed junction=roundabout as some entrances have right of way. See http://wiki.openstreetmap.org/wiki/Tag:junction%3Droundabout
# 2 lit      yes                                                                                                                              
# 3 maxspeed 30 mph                                                                                                                           
# 4 oneway   yes                                                                                                                              
# 5 surface  asphalt                                                                                                                          
# 6 lit      no                                                                                                                               
# 7 foot     designated                                                                                                                       
# 8 horse    designated                                                                                                                       
# 9 bicycle  yes                                                                                                                              
#10 surface  gravel                                                                                                                           
#11 old_name Freshwater, Yarmouth & Newport Railway                                                                                           
#12 prow_ref F61       

data

str1 <- c("\"comment\"=>\"Removed junction=roundabout as some entrances have right of way. See http://wiki.openstreetmap.org/wiki/Tag:junction%3Droundabout\",\"lit\"=>\"yes\",\"maxspeed\"=>\"30 mph\",\"oneway\"=>\"yes\",\"surface\"=>\"asphalt\"", 
"\"lit\"=>\"no\",\"foot\"=>\"designated\",\"horse\"=>\"designated\",\"bicycle\"=>\"yes\",\"surface\"=>\"gravel\",\"old_name\"=>\"Freshwater, Yarmouth & Newport Railway\",\"prow_ref\"=>\"F61\""
)
Related