первая строка для неагрегированных функций - PullRequest
1 голос
/ 07 ноября 2011

Я использую ddply, чтобы избежать лишних вычислений.

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

ddply(baseball,.(id,year),function(x){paste(x$id,x$year,sep="_")})

Error in list_to_dataframe(res, attr(.data, "split_labels")) : 
  Results do not have equal lengths

Мне нужно взять первый ряд каждого мини-фрейма данных.

ddply(baseball,function(x){paste(x$id[1],x$year[1],sep="_")})

Есть какой-то другой подход или помощник, которого я должен использовать? Этот синтаксис кажется неуклюжим.

-

Примечание: вставка в моем примере только для галочки - не воспринимайте это слишком буквально. Представьте, что это актуальная функция:

ddply(baseball,function(x){the_slowest_function_ever(x$id[1],x$year[1])})

Ответы [ 2 ]

3 голосов
/ 22 ноября 2011

В этом случае вам может показаться, что data.table немного проще и быстрее. Эквивалент .() переменных: by=:

DT[, { paste(id,year,sep="_") }, by=list(id,year) ]

или

DT[, { do.call("paste",.BY) }, by=list(id,year) ]

Я показал {}, чтобы проиллюстрировать, что вы можете поместить любое (многострочное) анонимное тело в j (вместо функции), но в этих простых примерах вам не нужен {}.

Переменные группирования имеют длину 1 внутри области действия каждой группы (что, по-видимому, является тем, о чем вы спрашиваете), для скорости и удобства. .BY также содержит группирующие переменные в одном объекте списка для общего доступа, когда критерии by определяются программно на лету; то есть, когда вы не знаете заранее by переменных.

1 голос
/ 07 ноября 2011

Вы можете использовать:

ddply(baseball, .(id, year), function(x){data.frame(paste(x$id,x$year,sep="_"))})

Когда вы возвращаете вектор, собирая его обратно в виде data.frame, каждая запись становится столбцом.Но есть разные длины, поэтому они не имеют одинаковое количество столбцов.Обернув его в data.frame(), вы убедитесь, что ваша функция возвращает data.frame с нужным столбцом, а не полагается на неявное (и в данном случае неправильное) преобразование.Кроме того, вы можете легко назвать новый столбец в этой конструкции.

ОБНОВЛЕНИЕ:

Если вы хотите оценить функцию только один раз (что разумно), то вы можете просто потянуть первую строкуи работать над этим.

ddply(baseball, .(id, year), function(x) {
  x <- x[1,]
  paste(x$id, x$year, sep="_")
})

Это (само по себе) будет иметь только одну строку для каждой комбинации id / year.Если вы хотите, чтобы в нем было столько же строк, сколько в оригинале, вы можете объединить это с предыдущей идеей.

ddply(baseball, .(id, year), function(x) {
  firstrow <- x[1,]
  data.frame(label=rep(paste(firstrow$id, firstrow$year, sep="_"), nrow(x)))
})
...