R

时间:2018-09-09 13:19:07

标签: r string subset

向量(df $ location1)中的一个字符串如下:

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

向量中的其余数据遵循相同的模式。我想将字符串的每个组成部分分成一个单独的数据元素,并将其放在新列中,例如:df $ city,df $ state等。

到目前为止,我已经能够隔离出纬度。长。通过执行以下操作将数据放入单独的列:

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

我可以通过在线查看其他代码来使其工作,但我并不完全理解。我了解正则表达式模式,但不了解“ \\ 1”部分。由于我不完全了解它,因此无法使用它来对同一字符串的其他部分进行子集化。

  • 像这样子集数据的最佳方法是什么?
  • 使用正则表达式是一种很好的方法吗?我还应该研究什么其他方式?

我研究了用逗号分割字符串,使用正则表达式,使用scan()函数以及许多其他变体的子集。现在我都很困惑。谢谢

5 个答案:

答案 0 :(得分:2)

我们还可以使用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

答案 1 :(得分:1)

您可以尝试strsplitdata.table::tstrsplitstrsplit + 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和引用名称可能包含空格,则可以尝试采用以下两种方法:

# 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, ' ')

答案 2 :(得分:1)

这里是使用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

答案 3 :(得分:0)

因此,此过程可能会更长一些,但是对我来说,这很清楚。与使用中断相反,下面我通过为每个所需值使用特定的正则表达式来标识值。我制作了一个正则表达式向量来提取每个值,一个向量用于变量名,然后使用循环从这些向量中提取并创建数据帧。

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()
})

答案 4 :(得分:-1)

\\1是正则表达式中的back reference。它类似于通配符(*),它将捕获您搜索词的所有实例,而不仅仅是它找到的第一个实例。