I have a data frame where one column is a list of keystrokes. I have then created a custom function to convert the list of keystrokes into the final word. As a concrete example, I start with this data:
dat <- data.frame(word=c(1,1,2,2,2,2),
key=c("a","b","a","b","Backspace","c"))
I then call the below to create a column with lists of keystrokes (the repeats are intentional, as I need to preserve every individual keystroke):
dat <- dat %>%
group_by(word) %>%
mutate(key_list = I(list(key))) %>%
ungroup()
This creates a data frame where the first 2 rows have key_list = a,b
and the last 4 rows are a,b,Backspace,c
. This is to be expected.
I then want to concatenate the key_list into a single string. However, I've created the custom function below because when iterating through the list, if I encounter "Backspace", I need to delete the last keystroke. Therefore, the function looks like:
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)
}
When I run this function in isolation, it returns the correct result:
19:13:11> word_list_to_final_str(c("a","b","Backspace","c"))
[1] "ac"
However, when I run the function within mutate()
, I get an additional column with all "abababbackspacecabbackspacecabbackspacecabbackspacec".
dat <- dat %>%
mutate(final_word = word_list_to_final_str(key_list))
Clearly somewhere the function is not clearing the list, but I cannot understand where. How can I change the function?
CodePudding user response:
Since you have a list column, you need to map over that list. You can use purrr
to make that pretty easy
dat %>%
group_by(word) %>%
mutate(key_list = I(list(key))) %>%
mutate(final_word = purrr:::map_chr(key_list, word_list_to_final_str))
An every more "tidy" way to do this would be to use tidyr::nest
as well
dat %>%
tidyr::nest(key_list = c(key)) %>%
mutate(final_word = purrr::map_chr(key_list, ~word_list_to_final_str(.x$key)))
CodePudding user response:
Without writing the function, you could do:
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