Как gsub для сопоставления строк и одновременно удалить несовпадающие строки? - PullRequest
0 голосов
/ 03 июня 2019

У меня есть фрейм данных со столбцом строк, который я хочу добавить к следующим категориям: город, страна и континент. Я использовал gsub для замены всех городов на «Город», всех стран на «Страна» и всех континентов на «Континент».

#This is what I have
dataframe
Color     Letter     Words
red       A          Paris,Asia,parrot,Antarctica,North America,cat,lizard
blue      A          Panama,New York,Africa,dog,Tokyo,Washington DC,fish
red       B          Copenhagen,bird,USA,Japan,Chicago,Mexico,insect
blue      B          Israel,Antarctica,horse,South America,North America,turtle,Brazil

#This is what I want
dataframe
Color     Letter     New
red       A          City,Continent
blue      A          Country,City,Continent
red       B          City,Country
blue      B          Country,Continent


#This is the code I have so far
dataframe$New <- NA

#groups all the cities
dataframe$New <- lapply)dataframe$Words, function(x) {
   gsub("Paris|New York|Tokyo|Washington DC|Copenhagen|Chicago", "City", x)})

#groups all the countries
dataframe$New <- lapply)dataframe$Words, function(x) {
   gsub("Panama|USA|Japan|Mexico|Israel|Brazil", "Country", x)})

#groups all the continents
dataframe$New <- lapply)dataframe$Words, function(x) {
   gsub("Asia|Antarctica|Africa|North America|South America", "Continent", x)})

dataframe$Words <- NULL

Как сохранить запрет на перезапись в фрейме данных $ New каждый раз и как удалить лишние слова (например, рыба, лошадь, кошка)?

Приведенные выше данные являются примером, основанным на очень большом наборе данных. В наборе данных столбец Слова содержит много повторов. Ниже приведены примеры строк из фрейма данных $ Words:

Words
Panama,Paris
Panama,Israel,cat
Panama,Paris,horse,
Panama,Asia
Panama
Panama,Chicago
Israel,Chicago
Israel,lizard,Paris
Israel,Panama,horse,Africa
```

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Можно добавить несколько вызовов ifelse для проверки определенных строк:

dataframe$New <- paste(ifelse(grepl("Paris|New York|Tokyo|Washington DC|Copenhagen|Chicago", dataframe$Words), "City", "N/A"), 
                       ifelse(grepl("Panama|USA|Japan|Mexico|Israel|Brazil", dataframe$Words), "Country", "N/A"),
                       ifelse(grepl("Asia|Antarctica|Africa|North America|South America", dataframe$Words), "Continent", "N/A"),
                       sep=",")

dataframe$New <- gsub("N/A,|,N/A", "", dataframe$New)

dataframe

#   Color Letter                                                             Words                    New
# 1   red      A             Paris,Asia,parrot,Antarctica,North America,cat,lizard         City,Continent
# 2  blue      A               Panama,New York,Africa,dog,Tokyo,Washington DC,fish City,Country,Continent
# 3   red      B                   Copenhagen,bird,USA,Japan,Chicago,Mexico,insect           City,Country
# 4  blue      B Israel,Antarctica,horse,South America,North America,turtle,Brazil      Country,Continent

Или версия сушилки с do.call + lapply:

strs <- list(c("Paris|New York|Tokyo|Washington DC|Copenhagen|Chicago", "City"),
             c("Panama|USA|Japan|Mexico|Israel|Brazil", "Country"),
             c("Asia|Antarctica|Africa|North America|South America", "Continent"))

df$New2 <- do.call(paste,
                   c(lapply(strs, function(s) ifelse(grepl(s[1], df$Words), s[2], "N/A")), 
                     list(sep=",")))
df$New2 <- gsub("N/A,|,N/A", "", df$New2)
0 голосов
/ 03 июня 2019

Может быть лучше создать пару ключ / значение list, а затем извлечь элементы после замены, сопоставив '100 * * ключа

library(gsubfn)
# key val list
lst1 <- list(Paris = "City", `New York` = "City", Tokyo = "City", 
  `Washington DC` = "City", 
    Copenhagen = "City", Chicago = "City", Panama = "Country", 
    USA = "Country", Japan = "Country", Mexico = "Country", Israel = "Country", 
    Brazil = "Country", Asia = "Continent", Antarctica = "Continent",      
    Africa = "Continent", `North America` = "Continent", 
    `South America` = "Continent")

Извлеките совпадающие значения с помощью strapply в list, переберите list с sapply и paste unique строками, которые являются 'City', 'Continent' или 'Country'

nm1 <- c("City", "Continent", "Country")
df1$New <- sapply(strapply(df1$Words,  "([^,]+)", lst1), function(x)  
        paste(unique(x[x %in% nm1]), collapse=","))
df1$New
#[1] "City,Continent"         "Country,City,Continent"
#[3] "City,Country"           "Country,Continent" 

Данные

df1 <- structure(list(Color = c("red", "blue", "red", "blue"), Letter = c("A", 
"A", "B", "B"), Words = c("Paris,Asia,parrot,Antarctica,North America,cat,lizard", 
"Panama,New York,Africa,dog,Tokyo,Washington DC,fish", 
  "Copenhagen,bird,USA,Japan,Chicago,Mexico,insect", 
"Israel,Antarctica,horse,South America,North America,turtle,Brazil"
)), class = "data.frame", row.names = c(NA, -4L))
...