case_when - странное поведение с символьными данными из фрейма данных - PullRequest
0 голосов
/ 07 января 2019

У меня есть программа для анализа и обработки текстовых данных, касающихся финансового плана счетов. Я пытаюсь реализовать соглашение об именовании на основе оператора case_when, извлекающего значения из разных фреймов данных. Когда я делаю это, я получаю результат символа (0) и не могу понять, почему.

Я не смог найти документацию по этой конкретной проблеме или общее ограничение длины символа для case_when. Я создал цикл for для проверки длины символов от 1 до 100 в выражении case_when, но у меня не возникло подобной проблемы, поэтому, похоже, это не так. Я подтвердил, что все мои классы совпадают.

# Example data frames
data.functions <- data.frame(
  Name = c("Insurance Services", "Cash"), Value = c("256800", "711000"),
  stringsAsFactors = F
)
data.objects <- data.frame(
  Name = "Payment to County", Value = "385", stringsAsFactors = F)
data.sources <- data.frame(
  Name = "Supply Resales", Value = "262", stringsAsFactors = F)

# Create value for i
i <- "E256800385"
# i <- "R000000262"
# i <- "B711000000"

# Split up the unique name ID
id_type <- substr(i, 1, 1)
id_func <- substr(i, 2, 7)
id_objsrc <- substr(i, 8, 10)

# Create name possibilities
# I split this out when the issue first occurred, originally this was
# directly in a mutate() statement
# Balance sheet account: Use function only
id_bal <- data.functions$Name[data.functions$Value == id_func]
# Expenditure account: Combine object and function
id_exp <- paste(
  data.objects$Name[data.objects$Value == id_objsrc],
  data.functions$Name[data.functions$Value == id_func],
  sep = " - "
  )
# Revenue account: Use source only
id_rev <- data.sources$Name[data.sources$Value == id_objsrc]

# # Alternative case
# id_bal <- "Bal"
# id_exp <- "Exp"
# id_rev <- "Rev"

# Select name based on ID type
id_name <- case_when(
  id_type == "B" ~ id_bal,
  id_type == "E" ~ id_exp,
  id_type == "R" ~ id_rev
)

Ожидаемый результат состоит в том, что id_name заполняется значением id_exp:

> id_exp
[1] "Payment to County - Insurance Services"

Что я получаю:

> id_name
character(0)

То же самое для двух других значений для i:

i <- "R000000262"
...
> id_name
character(0)

i <- "B711000000"
...
> id_name
character(0)

Однако, если я использую альтернативный регистр для возможностей имени, код функционирует как ожидалось:

id_bal <- "Bal"
id_exp <- "Exp"
id_rev <- "Rev"
...
> id_name
[1] "Bal"

Это совершенно сбивает с толку!

1 Ответ

0 голосов
/ 07 января 2019

Итак, case_when требует, чтобы как LHS, так и RHS всей формулы имели длину 1 или n (все они должны быть эквивалентными). С вашим примером прямо сейчас, id_rev вызывает это неожиданное поведение, потому что имеет длину 0, в то время как другие RHS имеют длину 1.

id_rev
character(0)

length(id_rev)
[1] 0

Это может быть просто ошибкой в ​​примере кода для id_rev, но если вы ожидаете пустые значения, подобные этому, мы можем использовать определение альтернативной переменной.

Чтобы доказать, что id_rev является нарушителем спокойствия, вы можете настроить его даже на пустую строку, и она будет иметь приемлемую длину, т.е. 1.

id_rev <- ""
length(id_rev)
[1] 1

А затем поведение возвращается к ожидаемому.

dplyr::case_when(
  (id_type == "B") ~ id_bal,
  (id_type == "R") ~ id_rev,
  (id_type == "E") ~ id_exp
)
[1] "Payment to County - Insurance Services"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...