Concatenate two vectors while preserving order in R [duplicate] - r

This question already has answers here:
Interlacing two vectors [duplicate]
(2 answers)
Closed 3 years ago.
This is hard to explain, so I'll try and then leave a simple example. When I concatenate the vectors, I would like the first element of each vector next to each other, then the second elements next to each other, etc. See example below.
x <- c("a","b","c")
y <- c(1,2,3)
c(x,y)
[1] "a" "b" "c" "1" "2" "3"
However, I would like the following:
[1] "a" "1" "b" "2" "c" "3"
I'm sure there is an answer on here already, but I'm having trouble putting in the right search. Any help appreciated!

An option would be to rbind and then concatenate
c(rbind(x, y))
#[1] "a" "1" "b" "2" "c" "3"
and for general case when the vectors are not of same length, order on the sequence of elements concatentated
c(x, y)[order(c(seq_along(x), seq_along(y)))]
#[1] "a" "1" "b" "2" "c" "3"

Related

str_extract in a vector by position [duplicate]

This question already has answers here:
Extracting the nth character from a vector of strings [duplicate]
(2 answers)
Extract first N characters from each string in a vector
(1 answer)
Closed 1 year ago.
I have a vector like this
cod <- c("6W41_CH", "6W41_CL" ,"6WPS_AH", "7C01_BC", "7C01_BD", "7C01_BL", "7C2L_AH", "7C2L_BI", "7C2L_CJ",
"7C8V_BA", "7C8W_BA", "7CAH_AD")
I'm doing an iteration and for each time I'd like to have for the cod[i] only the letter in the 6th position. I was trying to use str_extract. How I can do?
Position based extraction should be faster and more efficient with substr. We can provide the start and stop positions which is 6
substr(cod, 6, 6)
#[1] "C" "C" "A" "B" "B" "B" "A" "B" "C" "B" "B" "A"
or with str_sub
library(stringr)
str_sub(cod, 6, 6)
#[1] "C" "C" "A" "B" "B" "B" "A" "B" "C" "B" "B" "A"
If we need to use str_extract, specify a regex lookaround stating that we need to extract the next character after 5 characters
str_extract(cod, '(?<=^.{5}).')
#[1] "C" "C" "A" "B" "B" "B" "A" "B" "C" "B" "B" "A"

Delete list conditional on the number of elements in R

I have a list L of unnamed comma separated character lists. Each list of characters is of unequal length. I need to drop the character lists that have less than 4 elements from L. How can this be done? Example L:
> L
[[1]]
[1] "A" "B" "C" "D"
[[2]]
[1] "E" "F" "G"
In the example above I would like to end up with:
> L
[[1]]
[1] "A" "B" "C" "D"
We can use lengths to get the length of the list elements as a vector, create a logical vector based on that and subset the list
L[lengths(L)>3]
#[[1]]
#[1] "A" "B" "C" "D"
A less optimized approach (used earlier) is to loop through the list elements with sapply, get the length and use that to subset
L[sapply(L, length)>3]
data
L <- list(LETTERS[1:4], LETTERS[5:7])

Create dataframe from list of lists in R [duplicate]

This question already has answers here:
R list of lists to data.frame
(6 answers)
Closed 6 years ago.
I have a variable out that is a list of lists and I want to format the first child list to a dataframe. Say my out looks like this:
[[1]]
[[1]]$id
[1] "1"
[[1]]$input
[1] "A" "B" "C"
[[2]]
[[2]]$id
[1] "2"
[[2]]$input
[1] "R" "S" "T"
class(out) and class(out[[1]]) confirms that this is a list of lists.
I want to create a "long" dataframe that should look like this:
id input
1 "A"
1 "B"
1 "C"
2 "R"
2 "S"
2 "T"
I tried:
lapply(out, function(x){
as.data.frame(x)
})
but this seems to do an cbind and creates new columns for each child list.
Any help is highly appreciated.
try
library(plyr)
ldply(out, as.data.frame)

How do I apply an index vector over a list of vectors?

I want to apply a long index vector (50+ non-sequential integers) to a long list of vectors (50+ character vectors containing 100+ names) in order to retrieve specific values (as a list, vector, or data frame).
A simplified example is below:
> my.list <- list(c("a","b","c"),c("d","e","f"))
> my.index <- 2:3
Desired Output
[[1]]
[1] "b"
[[2]]
[1] "f"
##or
[1] "b"
[1] "f"
##or
[1] "b" "f"
I know I can get the same value from each element using:
> lapply(my.list, function(x) x[2])
##or
> lapply(my.list,'[', 2)
I can pull the second and third values from each element by:
> lapply(my.list,'[', my.index)
[[1]]
[1] "b" "c"
[[2]]
[1] "e" "f"
##or
> for(j in my.index) for(i in seq_along(my.list)) print(my.list[[i]][[j]])
[1] "b"
[1] "e"
[1] "c"
[1] "f"
I don't know how to pull just the one value from each element.
I've been looking for a few days and haven't found any examples of this being done, but it seems fairly straight forward. Am I missing something obvious here?
Thank you,
Scott
Whenever you have a problem that is like lapply but involves multiple parallel lists/vectors, consider Map or mapply (Map simply being a wrapper around mapply with SIMPLIFY=FALSE hardcoded).
Try this:
Map("[",my.list,my.index)
#[[1]]
#[1] "b"
#
#[[2]]
#[1] "f"
..or:
mapply("[",my.list,my.index)
#[1] "b" "f"

R - generate all combinations from 2 vectors given constraints

I would like to generate all combinations of two vectors, given two constraints: there can never be more than 3 characters from the first vector, and there must always be at least one characters from the second vector. I would also like to vary the final number of characters in the combination.
For instance, here are two vectors:
vec1=c("A","B","C","D")
vec2=c("W","X","Y","Z")
Say I wanted 3 characters in the combination. Possible acceptable permutations would be: "A" "B" "X"or "A" "Y" "Z". An unacceptable permutation would be: "A" "B" "C" since there is not at least one character from vec2.
Now say I wanted 5 characters in the combination. Possible acceptable permutations would be: "A" "C" "Z" "Y" or "A" "Y" "Z" "X". An unacceptable permutation would be: "A" "C" "D" "B" "X" since there are >3 characters from vec2.
I suppose I could use expand.grid to generate all combinations and then somehow subset, but there must be an easier way. Thanks in advance!
I'm not sure wheter this is easier, but you can leave away permutations that do not satisfy your conditions whith this strategy:
generate all combinations from vec1 that are acceptable.
generate all combinations from vec2 that are acceptable.
generate all combinations taking one solution from 1. + one solution from 2. Here I'd do the filtering with condition 3 afterwards.
(if you're looking for combinations, you're done, otherwise:) produce all permutations of letters within each result.
Now, let's have
vec1 <- LETTERS [1:4]
vec2 <- LETTERS [23:26]
## lists can eat up lots of memory, so use character vectors instead.
combine <- function (x, y)
combn (y, x, paste, collapse = "")
res1 <- unlist (lapply (0:3, combine, vec1))
res2 <- unlist (lapply (1:length (vec2), combine, vec2))
now we have:
> res1
[1] "" "A" "B" "C" "D" "AB" "AC" "AD" "BC" "BD" "CD" "ABC"
[13] "ABD" "ACD" "BCD"
> res2
[1] "W" "X" "Y" "Z" "WX" "WY" "WZ" "XY" "XZ" "YZ"
[11] "WXY" "WXZ" "WYZ" "XYZ" "WXYZ"
res3 <- outer (res1, res2, paste0)
res3 <- res3 [nchar (res3) == 5]
So here you are:
> res3
[1] "ABCWX" "ABDWX" "ACDWX" "BCDWX" "ABCWY" "ABDWY" "ACDWY" "BCDWY" "ABCWZ"
[10] "ABDWZ" "ACDWZ" "BCDWZ" "ABCXY" "ABDXY" "ACDXY" "BCDXY" "ABCXZ" "ABDXZ"
[19] "ACDXZ" "BCDXZ" "ABCYZ" "ABDYZ" "ACDYZ" "BCDYZ" "ABWXY" "ACWXY" "ADWXY"
[28] "BCWXY" "BDWXY" "CDWXY" "ABWXZ" "ACWXZ" "ADWXZ" "BCWXZ" "BDWXZ" "CDWXZ"
[37] "ABWYZ" "ACWYZ" "ADWYZ" "BCWYZ" "BDWYZ" "CDWYZ" "ABXYZ" "ACXYZ" "ADXYZ"
[46] "BCXYZ" "BDXYZ" "CDXYZ" "AWXYZ" "BWXYZ" "CWXYZ" "DWXYZ"
If you prefer the results split into single letters:
res <- matrix (unlist (strsplit (res3, "")), nrow = length (res3), byrow = TRUE)
> res
[,1] [,2] [,3] [,4] [,5]
[1,] "A" "B" "C" "W" "X"
[2,] "A" "B" "D" "W" "X"
[3,] "A" "C" "D" "W" "X"
[4,] "B" "C" "D" "W" "X"
(snip)
[51,] "C" "W" "X" "Y" "Z"
[52,] "D" "W" "X" "Y" "Z"
Which are your combinations.

Resources