Как проанализировать пару значений ключа строки URL в R с несколькими условиями

У меня есть строка в следующем формате:

a <- c("first_name=James(Mr), cust_id=98503(ZZW_LG,WGE,zonaire),
       StartDate=2015-05-20, EndDate=2015-05-20, performance=best")

Моя цель состоит в том, чтобы получить окончательный результат в кадре данных, как показано ниже:

first_name   cust_id   start_date    end_date    performance           cust_notes
 James(Mr)     98503   2015-05-20  2015-05-20           best   ZZW_LG,WGE,zonaire

Я запустил следующий код:

a <- c("first_name=James(Mr), cust_id=98503(ZZW_LG,WGE,zonaire),
       StartDate=2015-05-20, EndDate=2015-05-20, performance=best")

split_by_comma <- strsplit(a,",")

split_by_equal <- lapply(split_by_comma,strsplit,"=")

Поскольку у custid есть дополнительные запятые и скобки, я не получаю желаемого результата.

Обратите внимание, что квадратные скобки в имени являются подлинными и нужны как есть.

3 ответа

Решение

Если ваш формат строки верен, это может быть быстрое решение:

library(httr)

a <- c("first_name=James(Mr), cust_id=98503(ZZW_LG,WGE,zonaire), StartDate=2015-05-20, 
        EndDate=2015-05-20, performance=best")

dat <- data.frame(parse_url(sprintf("?%s", gsub(",[[:space:]]+", "&", a)))$query, 
           stringsAsFactors=FALSE)

library(tidyr)
library(dplyr)

mutate(separate(dat, cust_id, into=c("cust_id", "cust_notes"), sep="\\("), 
       cust_notes=gsub("\\)", "", cust_notes))

##   first_name cust_id         cust_notes  StartDate    EndDate performance
## 1  James(Mr)   98503 ZZW_LG,WGE,zonaire 2015-05-20 2015-05-20        best

Экстраполяция:

  • gsub(",[[:space:]]+", "&", a) делает параметры похожими на компоненты строки запроса URL.
  • sprintf(…) сделать его похожим на фактическую строку запроса
  • parse_url (от httr) разделит пары ключ / значение и поместит их в список (с именем query) в возвращенном списке
  • data.frame будет хорошо…
  • separate разделит cust_id колонка для вас на ( на две колонки
  • mutate удалит ) в новом cust_notes колонка

Вот и вся вещь как "труба":

library(httr)
library(tidyr)
library(dplyr)
library(magrittr)

a <- c("first_name=James(Mr), cust_id=98503(ZZW_LG,WGE,zonaire), StartDate=2015-05-20, 
        EndDate=2015-05-20, performance=best")

a %>% 
  gsub(",[[:space:]]+", "&", .) %>% 
  sprintf("?%s", .) %>% 
  parse_url() %>% 
  extract2("query") %>% 
  data.frame(stringsAsFactors=FALSE) %>% 
  separate(cust_id, into=c("cust_id", "cust_notes"), sep="\\(") %>% 
  mutate(cust_notes=gsub("\\)", "", cust_notes))

который соответствует экстраполяции и (IMO) легче следовать.

Вы должны разделить это.

,(?![^()]*\\))

Тебе нужно lookahead.Это не будет разделено , в (). См. Демо.

https://regex101.com/r/uF4oY4/82

Для получения желаемого результата используйте

split_by_comma <- strsplit(a,",(?![^()]*\\))",perl=TRUE)

split_by_equal <- lapply(split_by_comma,strsplit,"=")

Поздний ответ, но опубликовал его, так как его очень просто понять и реализовать без использования каких-либо дополнительных пакетов

rawdf = read.csv("<your file path>", header = F, sep = ",", stringsAsFactors = F)
# Get the first row of the dataframe and transpose it into a column of a df
colnames = data.frame(t(rawdf[1,]))

# Split the values of the single column df created above into its key value
# pairs which are separated by '=' and save in a vector
colnames = unlist(strsplit(as.character(colnames$X1), "="))

# Pick up all the odd indexed values from the above vector (all odd places
# are colnames and even places the values associated with them)
colnames = colnames[seq(1,length(colnames),2)]

# Assign the extracted column names from the vector above to your original data frame
colnames(rawdf) = colnames

# Use the regex to extract the value in each field of the original df by
# replacing the 'Key=' pattern present in each field with an empty string 
for(i in 1:dim(rawdf)[2]) rawdf[,i] = gsub(paste(colnames[i],"=",sep=""), "", rawdf[,i])
Другие вопросы по тегам