Подмножество строк в R - PullRequest
0 голосов
/ 09 сентября 2018

Одна из строк в моем векторе (df $ location1) выглядит следующим образом:

Potomac, MD 20854\n(39.038266, -77.203413)

Остальные данные в векторе следуют той же схеме. Я хочу разделить каждый компонент строки на отдельный элемент данных и поместить его в новые столбцы, такие как: df $ city, df $ state и т. Д.

До сих пор я был в состоянии изолировать лат. долго. данные в отдельный столбец, выполнив следующие действия:

df$lat.long <- gsub('.*\\\n\\\((.*)\\\)','\\\1',df$location1)

Мне удалось заставить его работать, просматривая другие коды онлайн, но я не до конца понимаю. Я понимаю шаблон регулярных выражений, но не понимаю часть "\\ 1". Поскольку я не понимаю его полностью, я не смог использовать его для подмножества других частей этой же строки.

  • Каков наилучший способ для поднабора данных, подобных этому?
  • Является ли использование регулярных выражений хорошим способом сделать это? Какие еще способы я должен изучить?

Я рассмотрел разбиение строки после запятой, подмножество с использованием регулярных выражений, использование функции scan () и многие другие варианты. Теперь я все в замешательстве. Thx

Ответы [ 5 ]

0 голосов
/ 09 сентября 2018

Так что этот процесс может быть немного дольше, но для меня это проясняет ситуацию. В отличие от использования разрывов, ниже я определяю значения с помощью специального регулярного выражения для каждого значения, которое я хочу. Я создаю вектор регулярного выражения для извлечения каждого значения, вектор для имен переменных, а затем использую цикл для извлечения и создания кадра данных из этих векторов.

library(stringi)
library(dplyr)
library(purrr)

rgexVec <- c("[\\w\\s-]+(?=,)", 
         "[A-Z]{2}", 
         "\\d+(?=\\n)", 
         "[\\d-\\.]+(?=,)", 
         "[\\d-\\.]+(?=\\))")
varNames <- c("city", 
          "state", 
          "zip", 
          "lat", 
          "long")
map2_dfc(varNames, rgexVec, function(vn, rg) {
  extractedVal <- stri_extract_first_regex(value, rg) %>% as.list()
  names(extractedVal) <- vn
  extractedVal %>% as_tibble()
})
0 голосов
/ 09 сентября 2018

Вот вариант с использованием base R

read.table(text= trimws(gsub(",+", " ", gsub("[, \n()]", ",", dat$Data))), 
  header = FALSE, col.names = c("City", "State", "Zip", "Latitude", "Longitude"), 
      stringsAsFactors = FALSE)
#    City State   Zip Latitude Longitude
#1 Potomac    MD 20854 39.03827 -77.20341
0 голосов
/ 09 сентября 2018

Мы также можем использовать функцию separate из пакета tidyr (часть пакета tidyverse).

library(tidyverse)

# Create example data frame
dat <- data.frame(Data = "Potomac, MD 20854\n(39.038266, -77.203413)",
                  stringsAsFactors = FALSE)
dat
#                                         Data
# 1 Potomac, MD 20854\n(39.038266, -77.203413)

# Separate the Data column
dat2 <- dat %>%
  separate(Data, into = c("City", "State", "Zip", "Latitude", "Longitude"),
           sep = ", |\\\n\\(|\\)|[[:space:]]")
dat2
#      City State   Zip  Latitude  Longitude
# 1 Potomac    MD 20854 39.038266 -77.203413
0 голосов
/ 09 сентября 2018

\\1 - это back reference в регулярном выражении. Он похож на подстановочный знак (*), который будет захватывать все вхождения вашего поискового запроса, а не только первый найденный.

0 голосов
/ 09 сентября 2018

Вы можете попробовать strsplit или data.table::tstrsplit (strsplit + transpose):

> x <- 'Potomac, MD 20854\n(39.038266, -77.203413)'
> data.table::tstrsplit(x, ', |\\n\\(|\\)')
[[1]]
[1] "Potomac"

[[2]]
[1] "MD 20854"

[[3]]
[1] "39.038266"

[[4]]
[1] "-77.203413"

В общем, вы можете сделать это:

library(data.table)
df[c('city', 'state', 'lat', 'long')] <- tstrsplit(df$location1, ', |\\n\\(|\\)')

Шаблон ', |\\n\\(|\\)' говорит tstrsplit разделить на ", ", "\n(" или ")".

Если вы хотите разделить состояние, а имена zip и cite могут содержать пробелы, вы можете попробовать выполнить два действия:

# original split (keep city names with space intact)
df[c('city', 'state', 'lat', 'long')] <- tstrsplit(df$location1, ', |\\n\\(|\\)')
# split state and zip
df[c('state', 'zip')] <- tstrsplit(df$state, ' ')
...