我有一个函数从一串文本中提取月份,匹配特定模式(如MAR06):
library(dplyr)
pattern <- "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\\d{2,2}"
find_month <- function(x)
{
extracted <- str_extract(x, pattern)
month_string <- substr(extracted, 1, 3)
if(!is.na(month_string) && month_string[[1]] == 'MAY')
{
value <- 1
}
else
{
value <- -1
}
return(value)
}
为简化起见,我只是在这里查看月份是否为5月。 我手动测试时工作正常:
> find_month("HELLO THERE MAY06")
[1] 1
> find_month("BYE SEP12")
[1] -1
然而,当我在数据帧上调用它时,它总是为每一行返回1:
a = c("HELLO THERE MAY06", "BYE SEP12")
b = c(TRUE, FALSE)
df = data.frame(desc=a, other=b)
df_mutated <- mutate(df, month = find_month(desc))
df_mutated
desc other month
1 HELLO THERE MAY06 TRUE 1
2 BYE SEP12 FALSE 1
我做错了什么?
答案 0 :(得分:1)
要回答“我做错了什么”,你可以看看debugonce(find_month)
时会发生什么。 mutate
函数是矢量化的,因此extracted
将是匹配的向量,month_string
将是月份名称的向量。由于&&
返回长度为一的向量,因此您的代码会返回1
或-1
,具体取决于是否存在任何NA以及month_string
的第一个元素是否为{{1} (因为你使用'MAY'
)。
您可以将month_string[[1]]
替换为if
来提升您的mutate功能:
ifelse
那就是说,理查德suggestion使用find_month <- function(x) {
extracted <- str_extract(x, pattern)
month_string <- substr(extracted, 1, 3)
ifelse(!is.na(month_string) & month_string == 'MAY', 1, -1)
}
是明智的。
答案 1 :(得分:1)
我们可以使用str_detect
library(stringr)
library(dplyr)
df %>%
mutate(month = c(1, -1)[(str_detect(desc, "MAY")+1)] )
# desc other month
#1 HELLO THERE MAY06 TRUE -1
#2 BYE SEP12 FALSE 1
答案 2 :(得分:0)
假设desc
列中有不同的名称,您可以使用rowwise()
将非向量化函数应用于每一行:
R> df_mutated2 <- df %>% group_by(desc) %>% rowwise() %>% mutate(month = find_month(desc))
R> df_mutated2
Source: local data frame [2 x 3]
Groups: <by row>
desc other month
(chr) (lgl) (dbl)
1 HELLO THERE MAY06 TRUE 1
2 BYE SEP12 FALSE -1