R: Самодельная функция с токенизацией и% like% работает только на первом токене - PullRequest
1 голос
/ 27 апреля 2020

У меня есть фрейм данных из двух столбцов, причем второй столбец (блок) в основном содержит первое слово первого столбца (str). Пожалуйста, проверьте ниже:

> df <- data.frame(str = c("cups vegetable soup", "cup brown lentils", "carrot", "stalks celery"), unit = c("cups", "cup", NA, "stalks"), stringsAsFactors = FALSE)

> df
                  str   unit
1 cups vegetable soup   cups
2   cup brown lentils    cup
3              carrot   <NA>
4       stalks celery stalks

Я хочу стереть первое слово $ str, если оно соответствует соответствующему значению (в той же строке), в $ unit.

Для этой области Я создал функцию «DelFunction», изображенную ниже:

 DelFunction <- function(x, y) {
  tokens_x <- x[[1]]
  tokens_y <- y[[1]]
  if ((tokens_x %like% tokens_y) == TRUE) {
    regmatches(tokens_x, regexpr("[a-z]+", tokens_x)) <- ""
  }
  tokens_x
}

После этого я использовал sapply в соответствующей строке

df$str<- sapply(df$str, DelFunction, df$unit)

Я получаю следующий результат, как вы увидите, Код работает только для первой строки, где слово «чашки» удаляется.

> df
                str   unit
1    vegetable soup   cups
2 cup brown lentils    cup
3            carrot   <NA>
4     stalks celery stalks

Цель была в следующем:

> df
                str   unit
1    vegetable soup   cups
2    brown lentils    cup
3            carrot   <NA>
4             celery stalks

Кто-то знает, как подойти к проблеме ?

Спасибо!

1 Ответ

1 голос
/ 27 апреля 2020

Возможный ответ:

library(stringr)
library(dplyr, warn.conflicts = FALSE)

df <-
  data.frame(
    str = c(
      "cups vegetable soup",
      "cup brown lentils",
      "carrot",
      "stalks celery"
    ),
    unit = c("cups", "cup", NA, "stalks"),
    stringsAsFactors = FALSE
  )

df %>%
  mutate(str = trimws(str_replace(str, unit, ''))) %>%
  mutate(str = if_else(is.na(unit), df$str, str)) -> df2

df2
#>              str   unit
#> 1 vegetable soup   cups
#> 2  brown lentils    cup
#> 3         carrot   <NA>
#> 4         celery stalks

Еще один возможный ответ без изменения (большого) исходного кода:


library(DescTools)

df <-
  data.frame(
    str = c(
      "cups vegetable soup",
      "cup brown lentils",
      "carrot",
      "stalks celery"
    ),
    unit = c("cups", "cup", NA, "stalks"),
    stringsAsFactors = FALSE
  )

DelFunction <- function(x, y) {
  tokens_x <- x
  tokens_y <- paste0(y, "%")

  if ((tokens_x %like% tokens_y) == TRUE) {
    regmatches(tokens_x, regexpr("[a-z]+", tokens_x)) <- ""
  }
  trimws(tokens_x)
}

df$str <- sapply(df$str, DelFunction, df$unit)
df
#>              str   unit
#> 1 vegetable soup   cups
#> 2  brown lentils    cup
#> 3         carrot   <NA>
#> 4         celery stalks
...