patternpythonModerate
Generating Cartesian product of strings in R
Viewed 0 times
generatingstringscartesianproduct
Problem
Sometimes I need to create character vectors like this one:
Notice that this is actually the Cartesian product of the character vectors joined together with a
I came up with this helper function:
It handles arbitrary number of character vector parameters of arbitrary lengths. The
datanames <- c(
"europe_co2_min",
"europe_co2_max",
"europe_temperature_min",
"europe_temperature_max",
"asia_co2_min",
"asia_co2_max",
"asia_temperature_min",
"asia_temperature_max"
)Notice that this is actually the Cartesian product of the character vectors joined together with a
_:c('europe', 'asia')
c('co2', 'temperature')
c('min', 'max')I came up with this helper function:
combine 0) {
sapply(sapply(lx, function(x) paste(x, combine.inner(...), sep=sep)), c)
} else {
lx
}
}
paste(prefix, combine.inner(...), sep='')
}It handles arbitrary number of character vector parameters of arbitrary lengths. The
prefix parameter is for convenience. It's similar to having a single element vector as the first parameter, except the common separator sep will not be applied after it.- Is there an easier way that exists in R and I missed?
- Is there anything smelly about this code?
Solution
Your approach is an example of good R code. However, there is a base function that allows creating a cartesian product of strings,
Furthermore, instead of
If you use these functions, your code will be much shorter:
Examples:
interaction. This function creates a factor, and the levels are equivalent to the cartesian product.Furthermore, instead of
paste(..., sep = "") you can use paste0(...).If you use these functions, your code will be much shorter:
combine <- function(..., prefix = "", sep = "_") {
paste0(prefix, levels(interaction(..., sep = sep)))
}Examples:
s1 <- c('europe', 'asia')
s2 <- c('co2', 'temperature')
s3 <- c('min', 'max')
combine(s1)
# [1] "europe" "asia"
combine(s1, s2)
# [1] "europe_co2" "europe_temperature" "asia_co2" "asia_temperature"
combine(s1, s2, s3)
# [1] "europe_co2_min" "europe_co2_max" "europe_temperature_min"
# [4] "europe_temperature_max" "asia_co2_min" "asia_co2_max"
# [7] "asia_temperature_min" "asia_temperature_max"Code Snippets
combine <- function(..., prefix = "", sep = "_") {
paste0(prefix, levels(interaction(..., sep = sep)))
}s1 <- c('europe', 'asia')
s2 <- c('co2', 'temperature')
s3 <- c('min', 'max')
combine(s1)
# [1] "europe" "asia"
combine(s1, s2)
# [1] "europe_co2" "europe_temperature" "asia_co2" "asia_temperature"
combine(s1, s2, s3)
# [1] "europe_co2_min" "europe_co2_max" "europe_temperature_min"
# [4] "europe_temperature_max" "asia_co2_min" "asia_co2_max"
# [7] "asia_temperature_min" "asia_temperature_max"Context
StackExchange Code Review Q#58595, answer score: 17
Revisions (0)
No revisions yet.