R combine list items - r

I have a R list as following
mlist <- list(name = c('id','value'), type = c('bigint','float'))
I want to combine it in a way which I can end up with the following string
id bigint,value float
I searched but could not find a way to do that. Can someone let me know how can I do that without looping over rows, I want to be able to use something like apply function

With purrr, we can also do:
library(purrr)
toString(pmap(mlist, paste))
# [1] "id bigint, value float"
Another Base R approach:
toString(Reduce(function(x1, x2){
mapply(function(x2, y2){
paste(x2, y2, collapse = " ")
}, x1, x2)
}, mlist))
# [1] "id bigint, value float"

We can use Map
do.call(Map, c(f = c, unname(mlist)))
#$id
#[1] "id" "bigint"
#$value
#[1] "value" "float"
If it needs to be a single string, use paste
do.call(Map, c(f = paste, unname(mlist)))
If we need to get a vector as output use unlist
unlist(do.call(Map, c(f = paste, sep="_", unname(mlist))), use.names = FALSE)
#[1] "id_bigint" "value_float"
Or in tidyverse
library(purrr)
transpose(mlist) %>%
map(flatten_chr)
#[[1]]
#[1] "id" "bigint"
#[[2]]
#[1] "value" "float"

Similar to #avid_useR
library(purrr)
pmap_chr(mlist, paste)

Related

Pass vector of symbols as function argument and convert to character vector

I have a function that I want to pass as an argument a vector of symbols and then internally I want to convert that vector to a character vector.
Minimal example:
fun <- function(symbols = c(a, b, c)) {
# code to convert to character vector
}
fun()
Output:
[1] "a" "b" "c"
Here's an approach with rlang::quo_name:
library(rlang)
fun <- function(symbols = c(a, b, c)) {
symbols <- enquo(symbols)
string <- quo_name(symbols)
unlist(strsplit(gsub("(c\\(|\\)|\\s)","",string),","))
}
fun(c(apple, orange, pear))
#[1] "apple" "orange" "pear"
I suspect you're actually trying to solve another problem with this, so it probably makes sense to post that as another question.
Base R solution:
fun <- function(symbols = c(a, b, c)) {
# code to convert to character vector
return(unlist(strsplit(
gsub("c\\(|\\)|\\(|\\s+", "",
deparse(substitute(symbols))), ","
)))
}
fun()

combining elements in a list of lists in R

I have a list called samples_ID with 116 vectors, each vectors has three elements like these:
"11" "GT20-16829" "S27"
I wanna keep the 116 vectors, but combine the elements to a single element like this
"11_GT20-16829_S27"
I tried something like this
samples_ID_ <- paste(samples_ID, collapse = "_")
it returns a single vector, below is just a part of it:
..._c(\"33\", \"GT20-16846\", \"S24\")_c(\"33\", \"GT20-18142\", \"S72\")_c(\"34\", \"GT20-16819\", \"S50\")_c...
What am I doing wrong?
Can you help me please?
Thanks
A tidyverse option.
library(stringr)
library(purrr)
map(samples_ID, ~ str_c(., collapse = '_'))
# [[1]]
# [1] "11_GT20-16829_S27"
#
# [[2]]
# [1] "12_GT20-16830_S28"
Data
samples_ID <- list(c("11", "GT20-16829", "S27"), c("12", "GT20-16830", "S28"
))
In base R, we can use sapply
sapply(samples_ID, paste, collapse="_")
Another base R option using paste
do.call(paste, c(data.frame(t(list2DF(samples_ID))), sep = "_"))
or
do.call(paste, data.frame(do.call(rbind, samples_ID)), sep = "_"))

string split and interchange the position of string in R

I have a vector called myvec. I would like to split it at _ and interchange the position. What would be the simplest way to do this?
myvec <- c("08AD09144_NACC022453", "08AD8245_NACC657970")
Result I want:
NACC022453_08AD09144, NACC657970_08AD8245
You can do this with regex capturing data in two groups and interchanging them using back reference.
myvec <- c("A1_B1", "B2_C1", "D1_A2")
sub('(\\w+)_(\\w+)', '\\2_\\1', myvec)
#[1] "B1_A1" "C1_B2" "A2_D1"
We can use strsplit from base R
sapply(strsplit(myvec, "_"), function(x) paste(x[2], x[1], sep = "_"))
#[1] "NACC022453_08AD09144" "NACC657970_08AD8245"

How to convert a column with list to character in R?

I have a dataframe
df <- data.frame(files=c("A.Rat.in_vivo.Liver", "B.Rat.in_vivo.Liver", "C.Rat.in_vivo.Liver"))
df$Chem <- lapply(df$files, function(x) sapply(x, function (x) str_replace(x, ".Rat.in_vivo.Liver", "")))
When I check the type
sapply(df, typeof)
I get
files Chem
"integer" "list"
How can I convert the "list" to "Character"? I try to add as.character
df$Chem <- lapply(df$files, function(x) sapply(x, function (x) as.character(str_replace(x, ".Rat.in_vivo.Liver", ""))))
but the outcome is the same. Please help.
We can use unlist
df$Chem <- unlist(df$Chem)
str_replace is vectorized, so there is no need to loop with sapply/lapply
library(stringr)
df$Chem <- str_replace(df$files, fixed(".Rat.in_vivo.Liver"), "")
Or make use of str_remove
df$Chem <- str_remove(df$files, fixed(".Rat.in_vivo.Liver"))
df$Chem
#[1] "A" "B" "C"
sapply(df, typeof)
# files Chem
#"character" "character"
Also, this can be done in base R with sub
df$Chem <- sub(".Rat.in_vivo.Liver", "", df$files, fixed = TRUE)
NOTE: In R 4.0, the default behavior of data.frame is stringsAsFactors = FALSE, so the 'files' here is character instead of factor (storage mode is 'integer')
You only need to change lapplywhich returns a list to sapply. However, as other solutions point out, this is unnecessarily complicated.
df$Chem <- sapply(df$files, function(x) sapply(x, function (x) str_replace(x, ".Rat.in_vivo.Liver", "")))
sapply(df, typeof)
Returns:
files Chem
"integer" "character"

Looking up names in a data.frame with partial matching, need them sorted

I want to look up indexes of variables in a data.frame given a chain of (partial) variable names. An example:
df <- data.frame(var = c("az","bz","cz"), stringsAsFactors = FALSE)
Now I have a chain given as:
v <- c("a > b")
I'm now searching the sorted corresponding variable names in the data.frame.
I do this with:
df$var[grep(paste(trimws(unlist(strsplit(v, ">"))), collapse = "|"), df$var)]
[1] "az" "bz"
This works in the first example. For the second example this fails:
v <- c("b > a")
df$var[grep(paste(trimws(unlist(strsplit(v, ">"))), collapse = "|"), df$var)]
[1] "az" "bz"
It returns [1] "az" "bz", whereas I expect [1] "bz" "az".
How can I achieve this?
If you don't do it via regex (b|a) and leave them as a vector as that is derived from your strsplit() function, i.e. c(2,1), then by looping and using grep, you get the correct order, i.e.
df$var[sapply(trimws(unlist(strsplit(v, ">"))), function(i)grep(i, df$var))]
#[1] "bz" "az"

Resources