более быстрый способ использования sapply в цикле for

Я пытаюсь найти более быстрый способ запустить функцию, которая ищет медианное значение для каждого заданного дня за определенный промежуток времени. Есть ли более быстрый способ, чем запуск Sapply в цикле for?

for(z in unique(as.factor(df$group))){
all[[z]]<- sapply(period, function(x) median(df[x == df$date & df$group==z, 'y']))
}

Пример данных:

date<-as.Date("2011-11-01") + 
runif( 1000, 
       max=as.integer( 
           as.Date( "2012-12-31") - 
               as.Date( "2011-11-01")))
period<-as.Date(min(df$date):max(df$date), origin = "1970-01-01")
df <- data.frame(date=date, y = rnorm(1000), group=factor(rep(letters[1:4], each=250)))
2
nl ja de

2 ответы

Если я правильно понимаю, вы хотите разделить по группе , а затем вычислить медианный в течение каждой date . Вот решение data.table .

Edit: The problem was with the date format of your dataset. It seems to report the number of unique elements wrong. So, I had to recast it to POSIXct format.

df$date <- as.POSIXct(as.character(df$date), format="%Y-%m-%d")
require(data.table)
dt <- data.table(df)

setkey(dt, "date")
dt.out <- dt[, lapply(letters[1:4], 
          function(x) median(y[group == x])), by = date]

Это идентично выходу Виктора.

4
добавлено
Мне нужны столбцы для каждого фактора в группе (четыре столбца + столбец даты), а не один столбец для всех групп.
добавлено автор cconnell, источник
это также дает мне несколько значений за несколько дней
добавлено автор cconnell, источник

Here is a solution using base R function tapply

tapply(df$y, df$date, median)

Update. Judging by your comment above, you need one column for each group? That's also a one-liner:

tapply(df$y, list(df$date, df$group), median)
2
добавлено
Вот потенциальный источник вашей путаницы. Во-первых, давайте сделаем мой пример воспроизводимым - вставьте set.seed (1) в начале кода OP. Затем, пожалуйста, сравните length (unique (df $ date)) (дает 1000) с длиной (уникальный (формат (df $ date, "% Y /% m /% d")) ) (дает 391). Понимаете, почему? По какой-то причине уникальный тип не подходит для типов Date.
добавлено автор Victor K., источник
Да. На самом деле довольно запутанно, что объект Date может хранить две разные даты, которые имеют идентичное представление печати, но не идентичны: после x <- as.Date (c (1.1, 1.0), origin = "1970-01-01" ) , x [1] == x [2] возвращает FALSE .
добавлено автор Victor K., источник
Кстати, причина, по которой tapply работала правильно, состоит в том, что она преобразует свой второй аргумент в коэффициент, который усекает десятичные части дат.
добавлено автор Victor K., источник