1

The following list is the result of using st_intersects() of the sf package. It contains numeric vectors, varying by length:

require(sf)
require(tidyverse)

mylist <- structure(list(c(1L, 71L, 168L, 672L), c(1L, 71L, 99L, 619L), c(3L, 47L,51L),
                        c(32L, 43L, 76L, 78L, 318L, 411L), c(4L, 143L, 344L, 363L, 724L),
                        c(4L, 17L, 251L, 327L, 330L, 344L, 363L, 450L, 724L), 
                        c(44L, 75L, 79L, 124L, 172L, 204L, 339L, 350L, 382L, 383L,
                          404L, 405L, 409L, 540L, 554L, 562L, 605L, 623L, 661L, 689L),
                        c(405L, 605L), c(124L, 249L, 339L, 540L, 605L, 661L), 
                        c(8L, 13L, 175L, 187L)), predicate = "intersects",
                        region.id = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10"),
                        ncol = 825L, class = c("sgbp", "list"))

I would like to extract the numeric vectors from the list into a tibble (or dataframe) and preserve their ordering.

That is, I would like to obtain an object which looks like

ID   V1

1   1L
1   71L
1   168L
1   672L
2   1L
2   71L
2   99L
2   619L
...

How would I achieve the above, preferrably in dplyr?

camille
  • 16,432
  • 18
  • 38
  • 60
FlobbyDsk
  • 49
  • 5

2 Answers2

1

You could use enframe and then unnest :

tibble::enframe(df, name = 'ID', value = 'V1') %>% tidyr::unnest(V1)

# A tibble: 63 x 2
#      ID    V1
#   <int> <int>
# 1     1     1
# 2     1    71
# 3     1   168
# 4     1   672
# 5     2     1
# 6     2    71
# 7     2    99
# 8     2   619
# 9     3     3
#10     3    47
# … with 53 more rows

In base R, you can use Map :

do.call(rbind.data.frame, Map(cbind, ID = seq_along(df), V1 = df))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Thanks Ronak, the base R solution worked well! Trying the `dplyr` solution you suggested, I realised that I had to provide more information about my data structure. Hence the edit of my question. – FlobbyDsk Aug 28 '20 at 13:43
  • @FlobbyDsk Both the answers work for me as expected for the new data. What does it return to you? – Ronak Shah Aug 28 '20 at 13:53
  • I get the following error message _`x` must not have more than one dimension. `length(dim(x))` must be zero or one, not 2_ . `mylist` now is a two-dimensional object. – FlobbyDsk Aug 28 '20 at 14:04
  • I think you are using the wrong variable name. Try with the data in your post `tibble::enframe(mylist, name = 'ID', value = 'V1') %>% tidyr::unnest(V1)` Does it still give you the same error? – Ronak Shah Aug 28 '20 at 14:11
  • I did as you suggested and the error remains. This is strange indeed – FlobbyDsk Aug 28 '20 at 14:21
  • I think it is issue with package version. Mine is `packageVersion('tibble') #[1] ‘3.0.2’` and `packageVersion('tidyr') [1] ‘1.1.0’` Maybe you need to update your packages? – Ronak Shah Aug 28 '20 at 14:36
  • it seems like I have relatively newer packages `packageVersion('tibble') #[1] ‘3.0.3` and `packageVersion('tidyr') # [1] ‘1.1.2’`. I am guessing this may be the problem. – FlobbyDsk Aug 28 '20 at 18:05
  • @FlobbyDsk I just updated the packages to the latest version which is now same as yours and I still get the output as shown without any error. Are you using the same data as shown in your post or using some other data? – Ronak Shah Aug 29 '20 at 02:19
1

A base solution with stack():

setNames(stack(setNames(mylist, seq_along(lst)))[2:1], c("ID", "V1"))

#    ID  V1
# 1   1   1
# 2   1  71
# 3   1 168
# 4   1 672
# 5   2   1
# 6   2  71
# 7   2  99
# 8   2 619
# ...
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51