I would like to flatten this list of arguments
args <- list(
a = 1,
b = "2",
list = list(c = 3, d = list(d1 = 5, d2 = 6)),
e = data.frame(e1 = c("a", "b"), e2 = c(7, 8))
)
on this
args <- list(
a = 1,
b = "2",
c = 3,
d = list(d1 = 5, d2 = 6),
e = data.frame(e1 = c("a", "b"), e2 = c(7, 8))
)
Because I need get work this function call
g <- function(x, y, ...){
do.call(f, x, y, ...)
}
g(x = x1, y = y1, args)
That does not work:
reduce(
.x = args,
.f = function(x) {
ifelse(
is.list(x),
lapply(x, `[[`),
x
)
}
)
that throws
Error in fn(out, elt, ...) : unused argument (elt)
CodePudding user response:
Update: to OPs new data:
purrr::c(flatten(args[1:3]), args[4])
$a
[1] 1
$b
[1] "2"
$c
[1] 3
$d
$d$d1
[1] 5
$d$d2
[1] 6
$e
e1 e2
1 a 7
2 b 8
As you already state in your question "I would like to flatten this list of arguments" -> We could use purrr
s flatten()
function:
library(purrr)
flatten(args)
$a
[1] 1
$b
[1] "2"
$c
[1] 3
$d
$d$d1
[1] 5
$d$d2
[1] 6
$e
[1] 5
CodePudding user response:
You can try the code below using for
loops
res <- c()
for (v in args) {
if (is.list(v) & !is.data.frame(v)) {
res <- c(res,v)
} else {
res <- c(res, list(v))
}
}
or via Reduce
res <- Reduce(
function(x,y) {
c(x, ifelse(is.list(y) & !is.data.frame(y), I, list)(y))
},
args,
c()
)
and you will obtain
> res
[[1]]
[1] 1
[[2]]
[1] "2"
$c
[1] 3
$d
$d$d1
[1] 5
$d$d2
[1] 6
[[5]]
e1 e2
1 a 7
2 b 8
CodePudding user response:
The output of map always be the same dim. So you need a for loop.
output <- NULL for (x in seq(length(args))) { list <- args[x] if (is.list(args[[x]]) && !is.data.frame(args[[x]])) { list <- flatten(args[x]) } output <- append(output, list) }
output
$a
[1] 1
$b
[1] "2"
$c
[1] 3
$d
$d$d1
[1] 5
$d$d2
[1] 6
$e
e1 e2
1 a 7
2 b 8