Как уменьшить размеры моего фрейма данных с точки зрения столбцов путем усреднения между столбцами? - PullRequest
2 голосов
/ 17 мая 2019

У меня есть кадр данных df1, который суммирует температуру воды каждые 2 метра до глубины 39 метров с течением времени.В качестве примера:

df1<-data.frame(Datetime=c("2016-08-18 00:00:00","2016-08-18 00:01:00","2016-08-18 00:02:00","2016-08-18 00:03:00"),
                Site=c("BD","HG","BD","HG"),
                m0=c(2,5,6,1),
                m2=c(3,5,2,4),
                m4=c(4,1,9,3),
                m6=c(2,5,6,1),
                m8=c(3,5,2,4),
                m10=c(2,5,6,1),
                m12=c(4,1,9,3),
                m14=c(3,5,2,4),
                m16=c(2,5,6,1),
                m18=c(4,1,9,3),
                m20=c(3,5,2,4),
                m22=c(2,5,6,1),
                m24=c(4,1,9,3),
                m26=c(3,5,2,4),
                m28=c(2,5,6,1),
                m30=c(4,1,9,3),
                m32=c(3,5,2,4),
                m34=c(2,5,6,1),
                m36=c(4,1,9,3),
                m38=c(3,5,2,4)
                )

> df1
             Datetime Site m0 m2 m4 m6 m8 m10 m12 m14 m16 m18 m20 m22 m24 m26 m28 m30 m32 m34 m36 m38
1 2016-08-18 00:00:00   BD  2  3  4  2  3   2   4   3   2   4   3   2   4   3   2   4   3   2   4   3
2 2016-08-18 00:01:00   HG  5  5  1  5  5   5   1   5   5   1   5   5   1   5   5   1   5   5   1   5
3 2016-08-18 00:02:00   BD  6  2  9  6  2   6   9   2   6   9   2   6   9   2   6   9   2   6   9   2
4 2016-08-18 00:03:00   HG  1  4  3  1  4   1   3   4   1   3   4   1   3   4   1   3   4   1   3   4

Я хотел бы рассчитать температуру воды для слоев 8 метров вместо 2 метров путем усреднения температуры воды между соответствующими столбцами.Например, я хотел бы преобразовать столбцы m0, m2, m4 и m6 в уникальный столбец с именем m3.5, который отражает среднюю температуру воды на глубине от 0 до 7 метров.

Как мой желаемый результат:

> df1
             Datetime Site m3.5 m11.5 m19.5 m27.5 m35.5
1 2016-08-18 00:00:00   BD 2.75  3.00  2.75  3.25  3.00
2 2016-08-18 00:01:00   HG 4.00  4.00  4.00  3.00  4.00
3 2016-08-18 00:02:00   BD 5.75  4.75  5.75  6.50  4.75
4 2016-08-18 00:03:00   HG 2.25  3.00  2.25  2.75  3.00

Кто-нибудь, как это сделать с dplyr?

Ответы [ 4 ]

2 голосов
/ 17 мая 2019

С tidyverse вы можете сделать что-то вроде этого:

df1 %>% 
  gather(var, val, -Datetime, -Site) %>% 
  mutate(group = rep(seq(3.5, 35.5, 8), each = 16)) %>% 
  group_by(group, Site, Datetime) %>% 
  summarise(value = mean(val)) %>% 
  spread(group, value)

  Site  Datetime            `3.5` `11.5` `19.5` `27.5` `35.5`
  <fct> <fct>               <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 BD    2016-08-18 00:00:00  2.75   3      2.75   3.25   3   
2 BD    2016-08-18 00:02:00  5.75   4.75   5.75   6.5    4.75
3 HG    2016-08-18 00:01:00  4      4      4      3      4   
4 HG    2016-08-18 00:03:00  2.25   3      2.25   2.75   3  
2 голосов
/ 17 мая 2019

вот решение, которое будет работать с любым количеством столбцов

num_meters <- 39
grp <- as.factor(cumsum(seq(0,num_meters, 2) %% 8 == 0))

df <- data.frame(df1[,c(1,2)], 
             t(apply(df1[,-c(1,2)], 1, function(x) tapply(x, grp, mean))))

#            Datetime Site   X1   X2   X3   X4   X5
#1 2016-08-18 00:00:00   BD 2.75 3.00 2.75 3.25 3.00
#2 2016-08-18 00:01:00   HG 4.00 4.00 4.00 3.00 4.00
#3 2016-08-18 00:02:00   BD 5.75 4.75 5.75 6.50 4.75
#4 2016-08-18 00:03:00   HG 2.25 3.00 2.25 2.75 3.00

# in case you also need the colnames that you have specified
colnames(df)[-c(1,2)] <- paste("m", tapply(seq(0,num_meters, 2), grp, mean) + 0.5, sep = "")
1 голос
/ 17 мая 2019

Следующее делает это.

library(dplyr)

df1 %>%
  mutate(m3.5 = rowMeans(.[3:6]),
         m11.5 = rowMeans(.[7:10]),
         m19.5 = rowMeans(.[11:14]),
         m27.5 = rowMeans(.[15:18]),
         m35.5 = rowMeans(.[19:22])) %>%
  select(Datetime, Site, m3.5:m35.5)
#             Datetime Site m3.5 m11.5 m19.5 m27.5 m35.5
#1 2016-08-18 00:00:00   BD 2.75  3.00  2.75  3.25  3.00
#2 2016-08-18 00:01:00   HG 4.00  4.00  4.00  3.00  4.00
#3 2016-08-18 00:02:00   BD 5.75  4.75  5.75  6.50  4.75
#4 2016-08-18 00:03:00   HG 2.25  3.00  2.25  2.75  3.00
1 голос
/ 17 мая 2019

Вы, наверное, ищете rowMeans:

df1$m3.5 <- rowMeans(df1[, c("m0", "m2", "m4", "m6")])

Нет необходимости в dplyr.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...