Making a custom function apply rowise in dplyr mutate
我有一个自定义布尔函数来检查一个字符串(我的实际函数比下面提供的要多,这只是作为说明性示例提供的)。
如果我将第一个版本与 dplyr::mutate() 一起使用,它只适用于第一个值,然后将所有行设置为那个答案。
我可以将函数package在 purr::map() 中,但是在较大的数据集上这似乎很慢。它似乎也不是 mutate 正常工作的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | library(tidyverse) valid_string <- function(string) { # Check the length if (stringr::str_length(string) != 10) { return(FALSE) } return(TRUE) } # Create a tibble to test on test_tib <- tibble::tibble(string = c("1504915593","1504915594","9999999999","123"), known_valid = c(TRUE, TRUE, TRUE, FALSE)) # Apply the function test_tib <- dplyr::mutate(test_tib, check_valid = valid_string(string)) test_tib valid_string2 <- function(string) { purrr::map_lgl(string, function(string) { # Check the length if (stringr::str_length(string) != 10) { return(FALSE) } return(TRUE) }) } # Apply the function test_tib <- dplyr::mutate(test_tib, check_valid2 = valid_string2(string)) test_tib |
我建议您将函数重写为
1 2 3 4 | valid_string <- function(string) { # Check the length ifelse(stringr::str_length(string) != 10, FALSE, TRUE) } |
另一个选项是
1 2 3 4 5 6 7 8 | valid_string2 <- function(string) { # Check the length if(stringr::str_length(string) != 10) { return(FALSE) } return(TRUE) } valid_string2 <- Vectorize(valid_string2) |
两者都工作得很好,但是我建议使用
的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # Create a tibble to test on test_tib <- tibble::tibble(string = c("1504915593","1504915594","9999999999","123"), known_valid = c(TRUE, TRUE, TRUE, FALSE)) # Apply the function test_tib <- dplyr::mutate(test_tib, check_valid = valid_string(string)) test_tib <- dplyr::mutate(test_tib, check_valid2 = valid_string2(string)) test_tib string known_valid check_valid check_valid2 <chr> <lgl> <lgl> <lgl> 1 1504915593 TRUE TRUE TRUE 2 1504915594 TRUE TRUE TRUE 3 9999999999 TRUE TRUE TRUE 4 123 FALSE FALSE FALSE |
这是你要找的吗?
1 | test_tib <- dplyr::mutate(test_tib, checkval = ifelse(nchar(string)!=10,FALSE,TRUE)) |