вырезать вектор с самоопределенными перерывами - PullRequest
2 голосов
/ 02 июля 2019

Я хотел бы сократить диапазон дат в соответствии с определенным breaks (0-7 дней, 8-15 дней, ..., 31-50 дней), а затем рассчитать среднее значение по группе значений.

library(dplyr)

date = seq(as.Date("2019/1/1"), by = "day", length.out = 50)
value = matrix(rnorm(200, 100, 50), nrow=50) %>% data.frame()
sample = cbind(date, value) %>% data.frame()

breaks = c(0, 7, 15, 30, 50)

sample %>%
  group_by(cutt = cut(StayDate, breaks=breaks)) %>%
  summarise(m1 = mean(X1), m2=mean(X2))

Однако, похоже, что функция cut может использовать только «день», «неделя» и т. Д. Для резки.Есть ли способ, которым я могу это сделать?

Ответы [ 3 ]

2 голосов
/ 02 июля 2019

Так как вы хотите разделить date на количество дней, вы можете вычесть каждое date с first date. Используя данные @ jay.sf

library(dplyr)

sample %>%
  mutate(new_date = as.integer(date - first(date)) + 1L) %>%
  group_by(cutt = cut(new_date, breaks = breaks)) %>%
  summarise_at(vars(X1, X2), mean)

# A tibble: 4 x 3
#  cutt     X1    X2
#  <fct>   <dbl> <dbl>
#1 (0,7]   126.  120. 
#2 (7,15]  123.   90.3
#3 (15,30]  82.6 107. 
#4 (30,50]  90.4 104. 

В вашем примере у вас есть последовательный date, но в случае, если есть разница между датами, этот код примет это во внимание, но я не уверен, предназначено ли это.

2 голосов
/ 02 июля 2019

Мы можем преобразовать в "factor" и обратно в "numeric".

library(dplyr)
sample %>%
  group_by(cutt=cut(as.numeric(factor(date)), breaks=breaks)) %>%
  summarise(m1=mean(X1), m2=mean(X2))
# # A tibble: 4 x 3
# cutt       m1    m2
# <fct>   <dbl> <dbl>
# 1 (0,7]   126.  120. 
# 2 (7,15]  123.   90.3
# 3 (15,30]  82.6 107. 
# 4 (30,50]  90.4 104. 

Или в базу R:

do.call(rbind, by(sample[2:3], cut(as.numeric(factor(sample$date)), breaks), colMeans))
#                X1        X2
# (0,7]   125.79941 120.01652
# (7,15]  122.82247  90.33681
# (15,30]  82.64698 107.13250
# (30,50]  90.39701 104.09779

Данные

set.seed(42)
n <- 50
sample <- data.frame(date=seq(as.Date("2019/1/1"), by="day", length.out=n),
                  matrix(rnorm(4*n, 100, 50), ncol=4, 
                         dimnames=list(NULL, paste0("X", 1:4))))
breaks <- c(0, 7, 15, 30, 50)
0 голосов
/ 02 июля 2019

Мы можем использовать data.table методы

library(data.table)
setDT(df1)[,lapply(.SD, mean) , .(cutt = cut(as.numeric(factor(date)), 
           breaks = breaks)), .SDcols = X1:X2]
#     cutt        X1        X2
#1:   (0,7] 125.79941 120.01652
#2:  (7,15] 122.82247  90.33681
#3: (15,30]  82.64698 107.13250
#4: (30,50]  90.39701 104.09779
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...