Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested, hierarchical data frames in R

I am new to R and I don't want to misunderstand the language and its data structure from the beginning on. :)

My data.frame sample.data contains beside 'normal' attributes (e.g. author) another, nested list of data.frame (files), which has e.g. the attributes extension.

How can I filter for authors who have created files with a certain extension? Is there a R-ic way of doing that? Maybe in this direction:

t <- subset(data, data$files[['extension']] > '.R')

Actually I want to avoid for loops.

Here you can find some sample data:

d1 <- data.frame(extension=c('.py', '.py', '.c++')) # and some other attributes
d2 <- data.frame(extension=c('.R', '.py')) # and some other attributes

sample.data <- data.frame(author=c('author_1', 'author_2'), files=I(list(d1, d2)))

The JSON the sample.data comes from looks like

[
    {
        "author": "author_1",
        "files": [
            {
                "extension": ".py",
                "path": "/a/path/somewhere/"
            },
            {
                "extension": ".c++",
                "path": "/a/path/somewhere/else/"
            }, ...
        ]
    }, ...
]
like image 399
Michael Dorner Avatar asked Dec 02 '25 22:12

Michael Dorner


1 Answers

There are at least a dozen ways of doing this, but if you want to learn R right, you should learn the standard ways of subsetting data structures, especially atomic vectors, lists and data frames. This is covered in chapter two of this book:

http://adv-r.had.co.nz/

There are other great books, but this is a good one, and it is online and free.

UPDATE: Okay, this converts your json to a list of data frames.

library("rjson")
s <- paste(c(
'[{' ,
'  "author": "author_1",',
'  "files": [',
'    {',
'     "extension": ".py",',
'     "path": "/a/path/somewhere/"',
'   },',
'   {',
'     "extension": ".c++",',
'     "path": "/a/path/somewhere/else/"',
'    }]',
'},',
'{',
'"author": "author_2",',
'"files": [',
'  {',
'    "extension": ".py",',
'    "path": "/b/path/somewhere/"',
'  },',
'  {',
'    "extension": ".c++",',
'    "path": "/b/path/somewhere/else/"',
'  }]',
'}]'),collapse="")

j <- fromJSON(s)

todf <- function (x) {
    nrow <- length(x$files)
    vext <- sapply(x$files,function (y) y[[1]])
    vpath <- sapply(x$files,function (y) y[[2]])
    df <- data.frame(author=rep(x$author,nrow),ext=vext,path=vpath)
}
listdf <- lapply(j,todf)
listdf

Which yields:

[[1]]
    author  ext                    path
1 author_1  .py      /a/path/somewhere/
2 author_1 .c++ /a/path/somewhere/else/

[[2]]
    author  ext                    path
1 author_2  .py      /b/path/somewhere/
2 author_2 .c++ /b/path/somewhere/else/

And to finish the task, merge and subset:

   mdf <- do.call("rbind", listdf)
   mdf[ mdf$ext==".py", ]

yielding:

    author ext               path
1 author_1 .py /a/path/somewhere/
3 author_2 .py /b/path/somewhere/
like image 55
Mike Wise Avatar answered Dec 04 '25 11:12

Mike Wise



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!