我有一个函数,当它通过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结合使用时,函数如何执行未编程的功能?我很沮丧!
答案 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_)
}