Изменить форму и вычислить среднее значение

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

clim <- read.table(text="alti    year    month    week    day    meanTemp    maxTemp    minTemp
350     2011    aug.     31      213    10          14         6
350     2011    aug.     31      214    12          18         6
350     2011    aug.     31      215    10          11         9
550     2011    aug.     31      213    8           10         6
550     2011    aug.     31      214    10          12         8
550     2011    aug.     31      215    8           9          7
350     2011    sep.     31      244    9           10         8
350     2011    sep.     31      245    11          12         10
350     2011    sep.     31      246    10          11         9
550     2011    sep.     31      244    7.5         9          6
550     2011    sep.     31      245    8           10         6
550     2011    sep.     31      246    8.5         9          8", header=TRUE)

и я пытаюсь изменить эти данные, чтобы иметь только одну строку на высоту и вычислять средние данные для каждого месяца и для всего года. Было бы здорово, если бы он имел такую ​​форму:

alti    mean_year(meanTemp)   mean_year(maxTemp)   mean_aug.(meanTemp)   mean_aug.(maxTemp)   mean_sep.(meanTemp)   [...]
350     10.333                12.667               10.667                14.3                 10                     ...
550     8.333                 9.833                8.667                 10.333               7.766                  ...

Любая идея выполнить это изменение формы и расчет?


person Community    schedule 23.07.2015    source источник
comment
Можете ли вы изменить данные, сделав их более удобными для пользователя, чтобы мы могли копировать/вставлять их в наши собственные сеансы (например, используя dput)?   -  person Roman Luštrik    schedule 23.07.2015
comment
Привет, Роман, user198275 только что изменил данные, так что теперь их легко вставить в R. Я не знал, что это возможно, отлично!! ;) Р.   -  person    schedule 23.07.2015


Ответы (3)


Вот еще один вариант решения data.table, но для этого требуется текущий devel version, v1.9.5:

require(data.table) # v1.9.5+
setDT(clim)
form = paste("alti", c("year", "month"), sep=" ~ ")
val  = c("meanTemp", "maxTemp")
ans  = lapply(form, function(x) dcast(clim, x, mean, value.var = val))
Reduce(function(x, y) x[y, on="alti"], ans)

#    alti meanTemp_mean_2011 maxTemp_mean_2011 meanTemp_mean_aug. meanTemp_mean_sep. maxTemp_mean_aug. maxTemp_mean_sep.
# 1:  350          10.333333         12.666667          10.666667                 10          14.33333         11.000000
# 2:  550           8.333333          9.833333           8.666667                  8          10.33333          9.333333
person Arun    schedule 23.07.2015

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

library(data.table)

setDT(clim)

merge(

clim[, list("mean_temp_mean_year" = mean(meanTemp), "max_temp_mean_year" = mean(maxTemp)), by = alti]
,
dcast(clim[, list("mean_temp_mean" = mean(meanTemp), "max_temp_mean" = mean(maxTemp)), by = c("alti","month")], alti ~ month, value.var = c("mean_temp_mean","max_temp_mean"))
,
by = "alti")

Я поменял имена некоторых переменных, и ваш порядок не идеален, но впоследствии их можно переупорядочить/переименовать.

person Chris    schedule 23.07.2015

Чтобы получить среднее значение месяцев или лет, вы можете использовать aggregate, а затем reshape.

Два агрегата можно вычислить по отдельности, а затем merge сложить их вместе:

mon <- aggregate(cbind(meanTemp, maxTemp) ~ month + alti, data=clim, FUN=mean)
mon.wide <- reshape(mon, direction='wide', timevar='month', idvar='alti')

yr <- aggregate(cbind(meanTemp, maxTemp) ~ year + alti, data=clim, FUN=mean)
yr.wide <- reshape(yr, direction='wide', timevar='year', idvar='alti')

Каждый из этих .wide наборов содержит нужные вам данные. Единственным общим столбцом является alti, поэтому мы берем значения по умолчанию merge:

 merge(mon.wide, yr.wide)
##   alti meanTemp.aug. maxTemp.aug. meanTemp.sep. maxTemp.sep. meanTemp.2011 maxTemp.2011
## 1  350     10.666667     14.33333            10    11.000000     10.333333    12.666667
## 2  550      8.666667     10.33333             8     9.333333      8.333333     9.833333
person Matthew Lundberg    schedule 23.07.2015
comment
Это решение не дает полного ответа. Не хватает только агрегированных значений по годам. - person SabDeM; 23.07.2015