2

In R, I have a list-of-lists that prints like this:

> ll <- list(list('fname'='joe', 'lname'='smith'), list('fname'='sally', 'lname'='smith'))                                         
> ll
[[1]]
[[1]]$fname
[1] "joe"

[[1]]$lname
[1] "smith"


[[2]]
[[2]]$fname
[1] "sally"

[[2]]$lname
[1] "smith"

But if I start with a dataframe (from a SQL query) and obtain a list-of-lists from the apply family of functions, it looks like this:

> ll2 <- apply(df, 1, as.list)
> ll2
$`1`
$`1`$fname
[1] "joe"

$`1`$lname
[1] "smith"


$`2`
$`2`$fname
[1] "sally"

$`2`$lname
[1] "smith"

So I would like to understand (1) what does the different notation signify---especially since both ll and ll2 seem to be a list-of-lists? (2) how can I convert ll2 (or better yet df) into something like ll?

For instance in this similar question every answer produces something like ll2 not ll. For instance lapply(split(df, 1:nrow(df)), as.list) still looks like ll2.

The only answer I've found so far is to loop over df and add a new item to a list as I go:

> ret <- list()
> ret[[1]] <- list('fname'='joe', 'lname'='smith')
> ret[[2]] <- list('fname'='sally', 'lname'='smith')
> ret
[[1]]
[[1]]$fname
[1] "joe"

[[1]]$lname
[1] "smith"


[[2]]
[[2]]$fname
[1] "sally"

[[2]]$lname
[1] "smith"

But I can see that R people frown on building lists in loops. So if you don't like that approach, what is a better one?

Community
  • 1
  • 1
Paul A Jungwirth
  • 23,504
  • 14
  • 74
  • 93
  • `x$name` works with named elements of lists. If your list doesn't have names, you have to use `x[[num]]` – Frank Jun 13 '16 at 17:20
  • 1
    Please be aware that `apply` is a very dangerous way to do anything with `data.frame`s. You are risking massive unwanted data coercion. A better idiom would be `lapply(split(df,nrow(df)),as.list)`. – joran Jun 13 '16 at 17:22
  • @joran thanks for the warning. I've also tried `lapply` but it still looks like `ll2` not `ll`. I updated the question to reflect that. – Paul A Jungwirth Jun 13 '16 at 17:24
  • @Frank so can you explain why `apply` and `lapply` create lists with "names" like `1` rather than lists without names? – Paul A Jungwirth Jun 13 '16 at 17:25
  • The only difference is the presence/absence of names. What specific problem are the names creating? If they aren't creating a concrete problem, what does it matter? – joran Jun 13 '16 at 17:27
  • @joran the library I'm using will only accept inputs like `ll` not `ll2`. – Paul A Jungwirth Jun 13 '16 at 17:33
  • 1
    Remove the names with `unname`. – joran Jun 13 '16 at 17:33
  • I agree with joran about just using unname. I am not sure why each fn behaves as it does with respect to naming the output, but it has never posed a problem / mattered for me. – Frank Jun 13 '16 at 17:36
  • Additionally, compare `list("2" = "A", "1" = "B")[[1]]` with `list("2" = "A", "1" = "B")$'1'`. For the sake of creating an `ll` from a "data.frame", you could use `.mapply(list, df, NULL)` – alexis_laz Jun 13 '16 at 18:29

0 Answers0