ddply : push or pull?
Does ddply push or pull when grouping data? I.e, does it involve many passes over the dat开发者_运维知识库a frame, or just one?
If you take a look at the code, you see the general structure of the function:
function (.data, .variables, .fun = NULL, ..., .progress = "none",
.drop = TRUE, .parallel = FALSE)
{
.variables <- as.quoted(.variables)
pieces <- splitter_d(.data, .variables, drop = .drop)
ldply(.data = pieces, .fun = .fun, ..., .progress = .progress,
.parallel = .parallel)
}
<environment: namespace:plyr>
so it basically rearranges the variables in a format that's easier to use, then breaks the data into pieces, and then use ldply on those pieces. Those pieces are generated by the function splitter_d. Pieces is actually a little bit more sophisticated than a list - it's a pointer to the original data and a list of indices. Whenever you request a piece of the list, it looks up the matching indices and extracts the appropriate data. This avoids having multiple copies of the data floating around. You can see how that functions using getAnywhere("splitter_d")
or plyr:::splitter_d
.
ldply passes once over every piece of data. After that, it combines everything back into a dataframe. Actually, in the help files of ldply is written:
All plyr functions use the same split-apply-combine strategy: they split the input into simpler pieces, apply .fun to each piece, and then combine the pieces into a single data structure. This function splits lists by elements and combines the result into a data frame. If there are no results, then this function will return a data frame with zero rows and columns (data.frame()).
I couldn't say it better myself. And miracle, the first sentence is to be found on the help page for ddply as well.
精彩评论