Reputation: 25703
Suppose I have a vector such as
vec <- 0:10
and a function such as
f <- function (x) x %% 3
Is there a builtin function in R that will break this vector into groups based on the return value of f
when applied to each element? If not, what is the most straightforward way to implement this using built-ins?
The expected return value is
list(c(0,3,6,9), c(1,4,7,10), c(2,5,8))
For a more complicated example, take a vector of strings, and group together those which are anagrams (i.e. they consist of the same letters). In this case, f
would take a string, lowercase it, and sort it. On Unix systems there's a word list available:
words <- scan('/usr/share/dict/words', what=character, sep='\n')
I do not insist on using these particular data structures (vector, list), if they are not the most appropriate for this task in R.
Upvotes: 2
Views: 4681
Reputation: 51
You could use dplyr
and transform the input into a data.frame
. From there, the code is easier to read:
library(dplyr)
data.frame(
value = vec,
stringsAsFactors = T
) %>%
mutate(
result = f(value)
) %>%
group_by(result) %>%
summarize(
list_result = list(value)
) %>%
.$list_result
Upvotes: 1
Reputation: 32548
split
can separate a vector into lists (among other things) based on factors. See ?split
for more information. I became interested in grouping vector of words based on anagrams. So here's one solution for that
vec = c("stop", "pots", "leaves")
split(vec, sapply(vec, function(x)
paste(sort(unlist(strsplit(tolower(gsub(" ", "", x)), ""))), collapse = "")))
#$aeelsv
#[1] "leaves"
#$opst
#[1] "stop" "pots"
Upvotes: 3