case_when-来自数据帧

时间:2019-01-07 17:25:25

标签: r dplyr

我有一个程序可以解析和处理有关财务会计图表的文本数据。我试图基于case_when语句实现命名约定,该语句从不同数据帧中提取值。当我这样做时,我得到了character(0)的结果,无法弄清原因。

我找不到有关此特定问题的任何文档,也找不到case_when的常规字符长度限制。我创建了一个for循环,以在case_when语句中测试从1到100的字符长度,但是没有遇到类似的问题,因此看起来并非如此。我已经确认我所有的课程都符合要求。

# 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 :(得分:1)

因此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"