Преобразовать объект «по» во фрейм данных в R - PullRequest
17 голосов
/ 12 апреля 2010

Я использую функцию «by» в R, чтобы разделить фрейм данных и применить функцию к различным частям, например:

pairwise.compare <- function(x) {
Nright <- ...
Nwrong <- ...
Ntied <- ...
return(c(Nright=Nright, Nwrong=Nwrong, Ntied=Ntied))
}
Z.by <- by(rankings, INDICES=list(rankings$Rater, rankings$Class), FUN=pairwise.compare)

Результат (Z.by) выглядит примерно так:

: 4 
: 357 
Nright Nwrong Ntied
     3      0     0
------------------------------------------------------------
: 8 
: 357 
NULL
------------------------------------------------------------
: 10 
: 470 
Nright Nwrong Ntied
     3      4     1 
------------------------------------------------------------ 
: 11 
: 470 
Nright Nwrong Ntied
    12      4     1

Я хотел бы, чтобы этот результат был преобразован в кадр данных (с отсутствующими записями NULL), чтобы он выглядел так:

  Rater Class Nright Nwrong Ntied
1     4   357      3      0     0
2    10   470      3      4     1
3    11   470     12      4     1

Как мне это сделать?

Ответы [ 5 ]

17 голосов
/ 12 апреля 2010

Функция by возвращает список, поэтому вы можете сделать что-то вроде этого:

data.frame(do.call("rbind", by(x, column, mean)))
8 голосов
/ 14 апреля 2010

Рассмотрите возможность использования ddply в пакете plyr вместо by. Он обрабатывает работу по добавлению столбца в ваш фрейм данных.

4 голосов
/ 18 февраля 2014

Старая тема, но для всех, кто ищет эту тему:

analysis = by(...)
data.frame(t(vapply(analysis,unlist,unlist(analysis[[1]]))))

unlist() будет принимать элемент вывода by() (в данном случае analysis) и выражать его как именованный вектор. vapply() выводит список всех элементов analysis и выводит результат. Требуется фиктивный аргумент, чтобы знать тип вывода, для чего и существует analysis[[1]]. Возможно, вам придется добавить проверку, что анализ не пуст, если это будет возможно. Каждый вывод будет столбцом, поэтому t() транспонирует его в нужную ориентацию, где каждая запись анализа становится строкой.

3 голосов
/ 17 июня 2015

Это расширяет решение Шейна по использованию rbind (), но также добавляет столбцы, идентифицирующие группы, и удаляет группы NULL - две функции, которые были запрошены в этом вопросе. При использовании функций базового пакета другие зависимости не требуются, например, plyr.

simplify_by_output = function(by_output) {
    null_ind = unlist(lapply(by_output, is.null))  # by() returns NULL for combinations of grouping variables for which there are no data. rbind() ignores those, so you have to keep track of them.
    by_df = do.call(rbind, by_output)  # Combine the results into a data frame.
    return(cbind(expand.grid(dimnames(by_output))[!null_ind, ], by_df))  # Add columns identifying groups, discarding names of groups for which no data exist.
}
2 голосов
/ 19 сентября 2016

Я бы сделал

x = by(data, list(data$x, data$y), function(d) whatever(d))
array(x, dim(x), dimnames(x))
...