Применение пользовательской функции к таблице - PullRequest
2 голосов
/ 28 июня 2019

Я создал пользовательскую функцию, которая будет искать текст для определенных значений и затем возвращать другое значение.Это прекрасно работает для каждого отдельного вызова, однако, когда я пытаюсь использовать его в Tidyverse, с mutate он больше не работает.Я получаю предупреждение:

Предупреждение:

In if (grepl ("Unique", textValue)) {: условие имеет длину> 1 и будет только первый элементused

Я предполагаю, что это как-то связано с типами и форматами, но не уверен, как это решить.

# create fake data
P1 = c("Unique Claims", "Unique Records", "Spend Today", "Spend Yesterday", "% Returned", "% Claimed")
P2 = as.tibble(P1) 


#create function
assignFormat <- function (textValue = as.character()) {
  if (grepl("Unique", textValue) > 0) {
    numFormat = "Comma"
  } else if (grepl("Spend", textValue) > 0) {
    numFormat = "Currency"
  } else if (grepl("%", textValue, ) > 0 ) {numFormat = "Percent"}
    else numFormat = "Other"

  return(numFormat)
}


#test function - works fine
assignFormat("% of CLaims")
assignFormat("Unique Records")
assignFormat("Total Spend")

#doesn't work
P3 = P2 %>%
     mutate(y = assignFormat(value))

Вещи, которые я пробовал: переход на grep с помощьюGREP в mutate напрямую - создает три вектора вместо

Опции и помощь приветствуются!

Ответы [ 3 ]

2 голосов
/ 28 июня 2019

Многие строковые функции работают как положено в dplyr, если вы используете rowwise группирование

#does work
P3 = P2 %>%
  rowwise() %>% 
  mutate(y = assignFormat(value)) %>% 
  ungroup()
2 голосов
/ 28 июня 2019

Чтобы использовать ту же функцию, вы можете использовать map варианты

library(dplyr)
library(purrr)

P2 %>%  mutate(y = map_chr(value, assignFormat))

# A tibble: 6 x 2
#  value            y       
#  <chr>           <chr>   
#1 Unique Claims   Comma   
#2 Unique Records  Comma   
#3 Spend Today     Currency
#4 Spend Yesterday Currency
#5 % Returned      Percent 
#6 % Claimed       Percent 

Вы также можете перейти на функцию, чтобы использовать ifelse вместо if

assignFormat <- function (textValue = as.character()) {
   ifelse(grepl("Unique", textValue), "Comma", 
          ifelse(grepl("Spend", textValue), "Currency", 
              ifelse(grepl("%", textValue),"Percent", "Other")))
}

P2 %>% mutate(y = assignFormat(value))

ИЛИ Другой вариант - использовать case_when, который предназначен для таких операций.

P2 %>%
  mutate(y = case_when(grepl("Unique", value) ~ "Comma", 
                       grepl("Spend", value) ~ "Currency", 
                       grepl("%", value) ~ "Percent", 
                       TRUE ~ "Other"))
1 голос
/ 28 июня 2019

Использование sapply:

> sapply(P2$value, assignFormat)
  Unique Claims  Unique Records     Spend Today Spend Yesterday      % Returned       % Claimed 
        "Comma"         "Comma"      "Currency"      "Currency"       "Percent"       "Percent" 

Чтобы добавить к фрейму данных:

P2 %>% 
  mutate(y = sapply(value, assignFormat))
# A tibble: 6 x 2
  value           y      
  <chr>           <chr>   
1 Unique Claims   Comma   
2 Unique Records  Comma   
3 Spend Today     Currency
4 Spend Yesterday Currency
5 % Returned      Percent 
6 % Claimed       Percent 

Сообщение об ошибке фактически информативно.Функция предназначена для работы с одним элементом, поэтому мы «векторизируем» его, используя семейство функций apply.Поскольку мы ожидаем одного результата на вход, мы используем sapply для возврата вектора результата.

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