r语言 - 自定义函数,当列表在隔离状态下工作时,操作列表在突变状态下不工作



我有一个数据框架,其中一列是击键列表。然后,我创建了一个自定义函数,将击键列表转换为最终单词。作为一个具体的例子,我从以下数据开始:

dat <- data.frame(word=c(1,1,2,2,2,2),
key=c("a","b","a","b","Backspace","c"))

然后调用下面的函数来创建一个包含按键列表的列(重复是有意的,因为我需要保留每个单独的按键):

dat <- dat %>% 
group_by(word) %>% 
mutate(key_list = I(list(key))) %>% 
ungroup()

这将创建一个数据帧,其中前2行具有key_list =a,b,最后4行是a,b,Backspace,c

然后我想将key_list连接到一个字符串中。但是,我创建了下面的自定义函数,因为在遍历列表时,如果遇到"backspace",我需要删除最后一个击键。因此,函数看起来像:

library(tidyverse)
word_list_to_final_str <- function(word_list) {
final_list = c()
for (i in word_list) {
if (tolower(i) %in% c(letters)) {
final_list <- c(final_list, tolower(i))
}
else if (i == 'Backspace') {
final_list <- head(final_list, -1)
}
}
final_str <- str_c(final_list,collapse="")
return(final_str)
}

当我单独运行这个函数时,它返回正确的结果:

19:13:11> word_list_to_final_str(c("a","b","Backspace","c"))
[1] "ac"

然而,当我在mutate()内运行该函数时,我得到了一个额外的列,其中包含所有" ababbackspacecabbackspacecabbackspacecabbackspacecabbackspacec& quot;

dat <- dat %>% 
mutate(final_word = word_list_to_final_str(key_list))

显然某个地方的函数没有清除列表,但我不明白在哪里。如何改变函数?

由于您有一个列表列,因此需要在该列表上进行映射。您可以使用purrr来使它变得非常简单

dat %>% 
group_by(word) %>% 
mutate(key_list = I(list(key))) %>% 
mutate(final_word = purrr:::map_chr(key_list, word_list_to_final_str))

每一个更"整洁";这样做的方法是使用tidyr::nest

dat %>% 
tidyr::nest(key_list = c(key)) %>% 
mutate(final_word = purrr::map_chr(key_list, ~word_list_to_final_str(.x$key)))

不编写函数,您可以这样做:

dat %>%
group_by(word)%>%
mutate(final_word = str_remove(str_c(key, collapse = ''), ".Backspace"))
# A tibble: 6 x 3
# Groups:   word [2]
word key       final_word
<dbl> <chr>     <chr>     
1     1 a         ab        
2     1 b         ab        
3     2 a         ac        
4     2 b         ac        
5     2 Backspace ac        
6     2 c         ac 

最新更新