Reputation: 1013
I am trying to build a query for an API and I have a function that is my parameters and values in a list. I am having problems if some of my parameters have multiple values. For example,
paramlist1 <- list(
a = "1",
b = "2",
c = "3",
d = "4"
)
paste(names(paramlist1), "=", paramlist1, collapse = "&", sep="")
works fine. But I have some parameters that can contain multiple values. For example,
paramlist2 <- list(
a = "1",
b = "2",
c = c("3", "4"),
d = c("5", "6")
)
I would like this to return me 2 strings:
a=1&b=2&c=3&d=5
and a=1&b=2&c=4&d=6
Maybe my approach to create this parameter list is not the best. Thanks
Upvotes: 3
Views: 111
Reputation: 887213
We check the lengths
of the list
, get the max
length ('mx'), based on that append the paramlist2
elements that have shorter length with NA
, stack
it to a two column data.frame
, fill
the NA
elements with the non-NA adjacent elements above, grouped by 'ind', create a sequence column, and then summarise
the 'ind' and 'value' by paste
ing the elements grouped by 'n'
library(tidyverse)
fn1 <- function(lst) {
mx <- max(lengths(lst))
map(lst, `length<-`, mx) %>%
stack %>%
fill(values) %>%
group_by(ind) %>%
mutate(n = row_number()) %>%
group_by(n) %>%
summarise(val = paste(ind, "=", values, collapse= "&", sep=""))
}
fn1(paramlist2)
# A tibble: 2 x 2
# n val
# <int> <chr>
#1 1 a=1&b=2&c=3&d=5
#2 2 a=1&b=2&c=4&d=6
On another list
with different length
of each elements 1, 2, and 3.
paramlist3 <- list(a = "1", b = "2", c = c("3", "4", "6"), d = c("5", "6"))
fn1(paramlist3)
# A tibble: 3 x 2
# n val
# <int> <chr>
#1 1 a=1&b=2&c=3&d=5
#2 2 a=1&b=2&c=4&d=6
#3 3 a=1&b=2&c=6&d=6
Here, we are assuming that the last non-NA element repeats itself to adjust the length
Upvotes: 1
Reputation: 8110
Here is another option. It looks like when you convert the list to a dataframe, it fills in the extra numbers for you. Then we just gather the results and summarize the output.
library(tidyverse)
paramlist2 <- list(
a = "1",
b = "2",
c = c("3", "4"),
d = c("5", "6")
)
paramlist2 %>%
as.data.frame() %>%
rownames_to_column("row") %>%
gather(col, num, -row) %>%
group_by(row) %>%
summarise(result = paste(col, "=", num, sep = "", collapse = "&"))
#> # A tibble: 2 x 2
#> row result
#> <chr> <chr>
#> 1 1 a=1&b=2&c=3&d=5
#> 2 2 a=1&b=2&c=4&d=6
Created on 2018-09-20 by the reprex package (v0.2.0).
Upvotes: 1
Reputation: 6073
You need to repeat the shorter vectors to be the same length as the longer vectors. One way to do this is to convert the list to a data.frame, then you can apply
your paste
function to each row:
myfun <- function(x) paste(names(x), "=", x, collapse="&", sep="")
apply(as.data.frame(paramlist2), 1, myfun)
Upvotes: 5