Использовать функцию str_detect для условного создания нового столбца в R-кадре данных? - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть фрейм данных со столбцом A, который содержит значения:

**Channel**
Direct
Paid social
Organic social

Что я хочу сделать: создать новый столбец с именем groupedChannel, где str_detect ищет строку в столбце A, чтобы добавить значение в groupedChannel.

Condition:
IF row in Column A matches regex "direct" THEN Column B value = "Direct" ELSE
IF row in Column B matches regex "social" THEN Column B value = "Social"

AFAIK, str_detect вернет только TRUE / FALSE. Как я могу использовать TRUE / FALSE, чтобы присвоить значение в столбце B?

Ответы [ 4 ]

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

Решение, использующее базовые функции регулярного выражения R, также обрабатывает, когда прямое и социальное значение не найдено в столбце Канал

# Dummy data
data <- data.frame(Channel = c("Direct Paid", "Social", "Organic", "Social Organic"),
                   stringsAsFactors = F)

# Use sapply to iterate through each value in the 'Channel' column in the above dataframe
data$groupChannel <- sapply(data$Channel, FUN = function(x){
  # Use base R regex functions to for conditions, and return values for new column
  if (grepl("direct", tolower(x))){
    return("Direct")
  }else if (grepl("social", tolower(x))){
    return("Social")
  }else{
    return("Direct or Social Not Found")
  }
})

head(data)
  Channel               groupChannel
1    Direct Paid                     Direct
2         Social                     Social
3        Organic Direct or Social Not Found
4 Social Organic                     Social
1 голос
/ 29 апреля 2020

У меня есть решение data.table, основанное на условной замене. Он использует grepl, но вы можете использовать stringr::str_detect, если хотите:

library(data.table)
setDT(df)
df[, groupedChannel := "Social"]

# Conditional replacement
df[grepl("direct",colA), groupedChannel := "Direct"]

(решение не проверено)

0 голосов
/ 29 апреля 2020

Вот решение base R, которое предполагает, что у вас есть четко определенный набор Channel_group значений

Данные:

data <- data.frame(Channel = c("Direct", "Paid social", "Organic social"),
                   stringsAsFactors = F)

Вы можете определить свои Channel_group значения в vector a:

a <- c("(S|s)ocial", "(D|d)irect")

Теперь вы используете sub для замены значений Channel на значения Channel_group; \\U гарантирует, что эти значения будут возвращены в виде строчных букв (используйте \\L, если вы предпочитаете использовать строчные буквы):

data$Channel_group <- sub(paste0(".*\\b(", paste(a, collapse = "|"),")\\b.*"), "\\U\\1", data$Channel, perl = T)

Результат:

data
         Channel Channel_group
1         Direct        DIRECT
2    Paid social        SOCIAL
3 Organic social        SOCIAL
0 голосов
/ 29 апреля 2020

Вы хотите, чтобы соответствовало вашему регулярному выражению, а не просто обнаружило .

library(dplyr)
library(stringr)

tibble(
  colA = c("**Channel**", "Direct", "Paid social", "Organic social")
) %>% 
  mutate(
    colB = str_match(colA, "[Ss]ocial|[Dd]irect")[,1],
    colB = str_to_lower(colB)
  )
#> # A tibble: 4 x 2
#>   colA           colB  
#>   <chr>          <chr> 
#> 1 **Channel**    <NA>  
#> 2 Direct         direct
#> 3 Paid social    social
#> 4 Organic social social

Создано в 2020-04-29 пакетом представ. (v0.3.0)

stringr::str_match возвращает матрицу, где первый столбец - это совпадение, а последующие столбцы - для нескольких групп, поэтому нам нужно поставить [,1] в конце этого вызова. Затем он соответствует версиям как в верхнем, так и в нижнем регистре, поэтому мы преобразуем все соответствующие группы в строчные.

В качестве альтернативы вы можете использовать str_extract примерно так: colB = str_extract(colA, "[Ss]ocial|[Dd]irect"), без [,1].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...