Bas Jansen
Bas Jansen

Reputation: 39

bind_rows for each result of a function in R

I want to have a data_frame with 1 row for each of my nodes.

library(tidyverse)
library(xml2)

nodeToDf <- function(theNode) {
  # More complex stuff here. But in the end it returns a data_frame with 1 row
  xml_attrs(theNode) %>%
    map_dfr(~as.list(.))
}  

data <- read_xml("<root><book title='First' pages='100'/><book title='Second' pages='100'/><book title='Third' pages='100'/></root>")
books <- xml_find_all(data, "//book")
map_df(books,nodeToDf)
# Error in bind_rows_(x, .id) : Argument 1 must have names

So my question is how can I get a data_frame with 1 row for each node in myNodeSet by calling a nodeToDf for each node?

Upvotes: 3

Views: 770

Answers (2)

De Novo
De Novo

Reputation: 7620

As the OPs comment says, the following produces the desired result, but s/he doesn't know how many rows there will be:

bind_rows(nodeToDf(books[1]), nodeToDf(books[2]), nodeToDf(books[3]))
# A tibble: 3 x 2
  title  pages
  <chr>  <chr>
1 First  100  
2 Second 100  
3 Third  100 

Your function already works with an arbitrary number of rows, see:

nodeToDF(books)
# A tibble: 3 x 2
  title  pages
  <chr>  <chr>
1 First  100  
2 Second 100  
3 Third  100 

The last line in your function body map_dfr(~as.list(.)) does exactly what you're looking for. Takes the elements of the list, and binds them together as rows of a data frame (vs. map_dfc, which would bind them as columns).

Upvotes: 0

Ayush Nigam
Ayush Nigam

Reputation: 384

try using rbind

rbind(myNodeset,nodeToDf)

Upvotes: 1

Related Questions