【问题标题】:Function behaving differently in mutate函数在 mutate 中表现不同
【发布时间】:2018-08-16 16:34:09
【问题描述】:

我有一个函数在通过 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 结合使用时,函数如何做一些它没有被编程做的事情?我被难住了!

【问题讨论】:

  • 我认为问题在于你的函数不能与向量一起正常工作。
  • 我认为您可能想围绕 ifelse 构建它,或者甚至更好的 case_when 而不是传统的 if/else 子句。前者是矢量化的。
  • 如何正确向量化函数?为什么向量化我的函数不会产生观察到的行为?谢谢。
  • 如果你在函数中使用purrr::maptidyr::unnest,你可以避免向量化。 test %&gt;% mutate(postal_area = map(post_code, pArea_parse)) %&gt;% unnest()

标签: r dplyr


【解决方案1】:

您对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_)
}

【讨论】:

  • 谢谢你,成功了。你知道我在哪里可以学习矢量化函数吗?我真的不明白为什么我的功能不起作用而你的功能却...
  • 这是我在谷歌上搜索到的第一件事:alyssafrazee.com/2014/01/29/vectorization.html。那里还有很多其他人。尝试搜索“r 矢量化函数”
  • 类似的答案,但在基础 R 中:pArea_parse &lt;- function(x) { z &lt;- grepl('[A-Z][A-Z]',substr(x,1,2)) y &lt;- grepl('[A-Z][0-9]',substr(x,1,2)) pArea &lt;- as.character(x) pArea[z] &lt;- substr(pArea[z],1,2) pArea[y] &lt;- substr(pArea[y],1,1) pArea[!y &amp; !z] &lt;- NA return(pArea) }
猜你喜欢
  • 2020-08-20
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多