captcoma
captcoma

Reputation: 1898

R: select a column of a dataframe column

I try to select columns that are located in data.frame columns. Sounds easy, however, I am at a loss..

library(tidyverse)

#test data
df <- tibble(name=c("a","b","c"),
            type=data.frame(motor=c(1,2,3),
            engine=c(1,2,3)),
            more=list(c(list(1,2,3),
                   list(2,3,4),
                   list(1,1,1))))

df
#> # A tibble: 3 x 3
#>   name  type$motor $engine more      
#>   <chr>      <dbl>   <dbl> <list>    
#> 1 a              1       1 <list [9]>
#> 2 b              2       2 <list [9]>
#> 3 c              3       3 <list [9]>

Created on 2020-06-23 by the reprex package (v0.3.0)

I would like to select the name and engine column.

I tried something like this without success:

df %>% select(name,$engine)

Upvotes: 1

Views: 180

Answers (2)

Ric S
Ric S

Reputation: 9247

Based on @RDRR's answer from this post, you can construct a custom function unnest_dataframes that iteratively unnests dataframes within dataframes. Afterwards, you just select the column type.engine (type because the internal dataframe is called so), and rename it to engine.

unnest_dataframes <- function(x) {
  y <- do.call(data.frame, x)
  if("data.frame" %in% sapply(y, class))
    unnest_dataframes(y)
  y
}

unnest_dataframes(df) %>% select(name, engine = type.engine)

Output

#   name engine
# 1    a      1
# 2    b      2
# 3    c      3

Upvotes: 2

r2evans
r2evans

Reputation: 160407

Because of you have a not-nested frame (as well as a nested list-column), the default view is to show you the columns broken out. One method is to transmute it out:

transmute(df, name, engine = type$engine)
# # A tibble: 3 x 2
#   name  engine
#   <chr>  <dbl>
# 1 a          1
# 2 b          2
# 3 c          3

Upvotes: 2

Related Questions