Как проанализировать пару значений ключа строки 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])