Szabolcs
Szabolcs

Reputation: 25703

Function to group elements of a vector/list

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

Answers (2)

Pierre Rebours
Pierre Rebours

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

d.b
d.b

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

Related Questions