appending to multiple elements of a list in R - r

Suppose you have a list foo containing some elements.
foo <- list()
foo[1:3] <- "a"
foo
# [[1]]
# [1] "a"
# [[2]]
# [1] "a"
# [[3]]
# [1] "a"
I would like to efficiently grow the list by both appending to existing elements and adding additional elements. For example adding "b" to elements 2:5, as simply as possible, preferably using foo[2:5]<-.
Desired output
# [[1]]
# [1] "a"
# [[2]]
# [1] "a" "b"
# [[3]]
# [1] "a" "b"
# [[4]]
# [1] "b"
# [[5]]
# [1] "b"

Oh this indeed works:
foo[2:5] <- lapply(foo[2:5], c, "b")
The c is the concatenation function.

Related

Creating result groups in R, using each element once (combination without repetition)

I have a dataset of 6 individuals: A,B,C,D,E,F
I want to group these into two groups of three individuals and have done so with the combn function in R:
m <- combn(n, 3)
This gives me all 20 possible groups where individuals occur in multiple groups. From this set of groups I then went to find all possible combinations of results, where each individual can only be used once.
I would like to do this using combinations without repetition:
C(n,r) = n! / r!(n-r)! and would therefore get 10 results that would look like this:
abc + def
abd + cef
abe + cdf
abf + cde
acd + bef
ace + bdf
acf + bde
ade + bcf
adf + bce
aef + bcd
I am not sure how to code this in R, from the list of groups that I have generated.
Edit: to generate the dataset I am using I have used the following code:
individuals <- c("a","b","c","d","e","f")
n <- length(individuals)
x <- 3
comb = function(n, x) {
factorial(n) / factorial(n-x) / factorial(x)
}
comb(n,x)
(m <- combn(n, 3))
numbers <- m
letters <- individuals
for (i in 1:length(numbers)) {
m[i] <- letters[numbers[i]]
}
In base R:
Create combnations of 3 letters and store it in a list (asplit)
Create new combnations of 2 groups (of 3 letters)
Filter the list to only keep combinations where the both parts have no element in common
individuals <- c("a","b","c","d","e","f")
combn(individuals, 3, simplify = FALSE) |>
combn(m = 2, simplify = FALSE) |>
Filter(f = \(x) !any(x[[1]] %in% x[[2]]))
output
[[1]]
[[1]][[1]]
[1] "a" "b" "c"
[[1]][[2]]
[1] "d" "e" "f"
[[2]]
[[2]][[1]]
[1] "a" "b" "d"
[[2]][[2]]
[1] "c" "e" "f"
[[3]]
[[3]][[1]]
[1] "a" "b" "e"
[[3]][[2]]
[1] "c" "d" "f"
[[4]]
[[4]][[1]]
[1] "a" "b" "f"
[[4]][[2]]
[1] "c" "d" "e"
[[5]]
[[5]][[1]]
[1] "a" "c" "d"
[[5]][[2]]
[1] "b" "e" "f"
[[6]]
[[6]][[1]]
[1] "a" "c" "e"
[[6]][[2]]
[1] "b" "d" "f"
[[7]]
[[7]][[1]]
[1] "a" "c" "f"
[[7]][[2]]
[1] "b" "d" "e"
[[8]]
[[8]][[1]]
[1] "a" "d" "e"
[[8]][[2]]
[1] "b" "c" "f"
[[9]]
[[9]][[1]]
[1] "a" "d" "f"
[[9]][[2]]
[1] "b" "c" "e"
[[10]]
[[10]][[1]]
[1] "a" "e" "f"
[[10]][[2]]
[1] "b" "c" "d"

Split a vector into non-overlapping sub-list with increasing length

Let's say I have this vector:
letters[1:7]
[1] "a" "b" "c" "d" "e" "f" "g"
I would like to split it into a non-overlapping list with increasing length of 1, and keep what is left behind (e.g. sub-list 4 should have 4 elements, but there's only one left, and I'd like to keep that one), like the following:
[[1]]
[1] "a"
[[2]]
[1] "b" "c"
[[3]]
[1] "d" "e" "f"
[[4]]
[1] "g"
Please do let me know any direction to solve this, thank you!
Example vector:
x <- letters[1:7]
Solution:
n <- ceiling(0.5 * sqrt(1 + 8 * length(x)) - 0.5)
split(x, rep(1:n, 1:n)[1:length(x)])
#$`1`
#[1] "a"
#
#$`2`
#[1] "b" "c"
#
#$`3`
#[1] "d" "e" "f"
#
#$`4`
#[1] "g"
Something quick'n dirty
splitter = function(x) {
n = length(x)
i = 1
while ( i * (i + 1L) / 2L < (n-i) ) i = i + 1
out = rep(i+1, n)
out[1:(i * (i + 1L) / 2L)] = rep(1:i, 1:i)
unname(split(x, out))
}
splitter(x)
[[1]]
[1] "a"
[[2]]
[1] "b" "c"
[[3]]
[1] "d" "e" "f"
[[4]]
[1] "g"
x <- letters[1:7]
splt <- rep(seq(length(x)), seq(length(x)))[seq(length(x))]
split(x, splt)
#> $`1`
#> [1] "a"
#>
#> $`2`
#> [1] "b" "c"
#>
#> $`3`
#> [1] "d" "e" "f"
#>
#> $`4`
#> [1] "g"
Created on 2022-08-04 by the reprex package (v2.0.1)

Extract all possible subsequences from vector in R [duplicate]

This question already has answers here:
Unordered combinations of all lengths
(3 answers)
Closed 2 years ago.
I would like to extract all possible subsequences from a vector of length n. For example if I have c("a","b","c") I would like to find c("a","b","c","ab","ac","bc","abc",""). I can solve this manually with vector of short lengths but the problem becomes intractable with longer lengths. Any idea how I can do this using some iteration?
Using combn.
x <- c("a","b","c")
unlist(sapply(1:length(x), function(i) combn(x, i, simplify=F)), recursive=F)
# [[1]]
# [1] "a"
#
# [[2]]
# [1] "b"
#
# [[3]]
# [1] "c"
#
# [[4]]
# [1] "a" "b"
#
# [[5]]
# [1] "a" "c"
#
# [[6]]
# [1] "b" "c"
#
# [[7]]
# [1] "a" "b" "c"
Or
unlist(sapply(1:length(x), function(i) combn(x, i, function(j) Reduce(paste0, j))))
# [1] "a" "b" "c" "ab" "ac" "bc" "abc"

Using rbind()/cbind() to append single row data in R

I have 6 numeric lists each containing different number of values i.e [1:350] , [1:450] .... . I am trying to append all of these lists into a singular list i.e [1:1050] using rbind(), but the output I get is dataframe of [1:350, 1:6].
Can someone please help me with this.
To concatenate multiple lists, you can use c()
x <- list(1, 2:5)
y <- list("A", "B")
z <- list(letters[1:5])
c(x, y, z)
# [[1]]
# [1] 1
#
# [[2]]
# [1] 2 3 4 5
#
# [[3]]
# [1] "A"
#
# [[4]]
# [1] "B"
#
# [[5]]
# [1] "a" "b" "c" "d" "e"

Convert or transform the list

Input list is:
$A
[1] 25
$B
[1] 22
$C
[1] 25
$D
[1] 26
----
Need to convert this to
$25
[1] "A" "C"
$22
[1] "B"
$26
[1] "D"
How do I change the grouping? Please help me.
If your list is called "L" (example below), try:
L <- list(A = 25, B = 22, C = 25, D = 26)
split(names(L), unlist(L))
# $`22`
# [1] "B"
#
# $`25`
# [1] "A" "C"
#
# $`26`
# [1] "D"
You could also try with(stack(L), split(as.character(ind), values)).

Resources