变异中的功能有所不同

时间:2018-08-16 16:34:10

标签: r dplyr mutate

我有一个函数,当它通过dplyr软件包的mutate函数传递时,行为不正确。该函数采用英国邮政编码,并返回一个邮政区。它适用于单个邮政编码或邮政编码矢量。

功能如下:

pArea_parse <- function(x) {
z <- any(grep('[A-Z][A-Z]',substr(x,1,2)))
y <- any(grep('[A-Z][0-9]',substr(x,1,2)))

if (z) {
    return(substr(x,1,2))
    }
else if (y) {
        return(substr(x,1,1))
        }
else if (!y & !z) {
    return(NA)
        }
}

有效:

x <- "B30 1AA" # plucked randomly from a postcode site
> pArea_parse(x)
[1] "B"

以下是一些示例数据:

test <- data.frame(id = c(1,2,3,4), post_code = c("B30 1AA", "B30 3FT", "B30 
3AZ", "BA1 8TU"))

这是我的dplyr代码:

test %>% mutate(postal_area = pArea_parse(post_code))

即使在邮编矢量或单个邮政编码中都不会发生此情况,它会返回字母和数字,而不是在字母后跟数字的情况下返回第一个字母。

id post_code postal_area
1   B30 1AA          B3
2   B30 3FT          B3
3   B30 3AZ          B3
4   BA1 8TU          BA

与mutate结合使用时,函数如何执行未编程的功能?我很沮丧!

1 个答案:

答案 0 :(得分:2)

您使用any()if/else会使函数无法向量化。也就是说,如果传入值向量,则不会得到正确的值向量。 这并非特定于mutate()。如果您在mutate之外尝试功能,则会得到相同的结果

pArea_parse(c("B30 1AA", "B30 3FT", "B30 3AZ", "BA1 8TU"))
# [1] "B3" "B3" "B3" "BA"

您可以使用dplyr辅助功能case_when来简化此操作。例如

pArea_parse <- function(x) {
  z <- grepl('[A-Z][A-Z]',substr(x,1,2))
  y <- grepl('[A-Z][0-9]',substr(x,1,2))

  case_when(z~substr(x,1,2),
            y~substr(x,1,1),
            TRUE~NA_character_)
}