Как рассчитать среднее значение первых 7 наблюдений на человека в кадре данных - PullRequest
0 голосов
/ 16 января 2020

У меня есть структура данных, подобная этой

>data
  ID  Location Sex   Time  Var1  Var2  Var3  Var4  Var5  Var6
   12     A     M     .1    …      …     …     …     …     … 
   12     A     M     .2    …      …     …     …     …     … 
   12     A     M     .3    …      …     …     …     …     … 
   12     A     M     .4    …      …     …     …     …     …
   12     A     M     .5    …      …     …     …     …     … 
   12     A     M     .6    …      …     …     …     …     … 
   234    A     M     .1    …      …     …     …     …     … 
   234    A     M     .2    …      …     …     …     …     … 
   234    A     M     .3    …      …     …     …     …     … 
   234    A     M     .4    …      …     …     …     …     … 
   234    A     M     .5    …      …     …     …     …     …  

Есть несколько сотен человек, каждый из которых имеет уникальный номер ID. Данные для каждого человека являются данными временного ряда. В реальных данных есть несколько сотен измерений на человека. Например, в приведенном выше примере есть только 6 наблюдений для отдельного 12 и 5 наблюдений для отдельного 234. В действительности индивидуальный 12 может иметь 980 наблюдений, а отдельный 234 может иметь 1249 наблюдений.

Как я могу получить R для возврата кадра данных со средним значением первых 7 наблюдений для каждого человека в этом формате:

ID  Location  Sex  Variable  Average
12     A        M      Var1     … 
12     A        M      Var2     … 
12     A        M      Var3     … 
12     A        M      Var4     … 
12     A        M      Var5     … 
12     A        M      Var6     … 
234    A        M      Var1     … 
234    A        M      Var2     … 
234    A        M      Var3     … 
234    A        M      Var4     … 
234    A        M      Var5     … 
234    A        M      Var6     … 

И как я могу сделать то же самое для последние 7 наблюдений для каждого человека (помните, что временные ряды для каждого человека имеют разную длину)

Ответы [ 2 ]

1 голос
/ 16 января 2020

Используя dplyr, вы должны иметь возможность повернуть data.frame, чтобы все ваши наблюдения были в одном столбце, отфильтровать для топ-7 по времени для каждого идентификатора и переменной и взять среднее значение.

library(dplyr)
library(readr) ## just to read OP's data

df <- readr::read_table("  ID   Location Sex   Time  Var1  Var2  Var3  Var4  Var5  Var6
   12     A     M     .1    a      a     a     a     a     a 
   12     A     M     .2    a      a     a     a     a     a 
   12     A     M     .3    a      a     a     a     a     a 
   12     A     M     .4    a      a     a     a     a     a
   12     A     M     .5    a      a     a     a     a     a 
   12     A     M     .6    a      a     a     a     a     a 
   234    A     M     .1    a      a     a     a     a     a 
   234    A     M     .2    a      a     a     a     a     a 
   234    A     M     .3    a      a     a     a     a     a 
   234    A     M     .4    a      a     a     a     a     a 
   234    A     M     .5    a      a     a     a     a     a ") %>%
  mutate_at(vars(contains("Var")), ~runif(11))

df %>%
  pivot_longer(contains("Var"), names_to = "Variable") %>%
  group_by(ID, Location, Sex, Variable) %>%
  top_n(7, desc(Time)) %>%
  summarize(Average = mean(value))
#> # A tibble: 12 x 5
#> # Groups:   ID, Location, Sex [2]
#>       ID Location Sex   Variable Average
#>    <dbl> <chr>    <chr> <chr>      <dbl>
#>  1    12 A        M     Var1       0.356
#>  2    12 A        M     Var2       0.528
#>  3    12 A        M     Var3       0.489
#>  4    12 A        M     Var4       0.613
#>  5    12 A        M     Var5       0.557
#>  6    12 A        M     Var6       0.730
#>  7   234 A        M     Var1       0.365
#>  8   234 A        M     Var2       0.557
#>  9   234 A        M     Var3       0.580
#> 10   234 A        M     Var4       0.626
#> 11   234 A        M     Var5       0.344
#> 12   234 A        M     Var6       0.534

И чтобы сделать последние 7, все, что вам нужно сделать, это изменить строку с top_n(7, desc(Time) на top_n(7, Time), чтобы установить самое высокое значение на самое низкое.

0 голосов
/ 16 января 2020

Вы можете использовать aggregate/reshape подход.

res <- reshape(aggregate(. ~ id + location + sex, data=dat, function(x) 
  mean(x[1:7]))[-4], varying=4:9, idvar=1:3, direction="long", sep="")
res[order(res$id), ]  # just a little order
#            id location sex time         var
# 12.A.M.1   12        A   M    1  0.23035482
# 12.A.M.2   12        A   M    2  0.67700690
# 12.A.M.3   12        A   M    3  0.12926876
# 12.A.M.4   12        A   M    4  0.06464387
# 12.A.M.5   12        A   M    5 -0.39031674
# 12.A.M.6   12        A   M    6 -0.21768911
# 234.A.M.1 234        A   M    1  0.17089758
# 234.A.M.2 234        A   M    2 -0.09195034
# 234.A.M.3 234        A   M    3  0.40042572
# 234.A.M.4 234        A   M    4  0.23404603
# 234.A.M.5 234        A   M    5  0.08176435
# 234.A.M.6 234        A   M    6  0.02859807

Или используя by

do.call(rbind, by(dat, dat$id, function(x) {
    cbind(x[1:6, 1:3], var=names(x[5:10]), mn=colMeans(x[1:7, 5:10]))
}))
#         id location sex  var          mn
# 12.1    12        A   M var1  0.23035482
# 12.3    12        A   M var2  0.67700690
# 12.5    12        A   M var3  0.12926876
# 12.7    12        A   M var4  0.06464387
# 12.9    12        A   M var5 -0.39031674
# 12.11   12        A   M var6 -0.21768911
# 234.2  234        A   M var1  0.17089758
# 234.4  234        A   M var2 -0.09195034
# 234.6  234        A   M var3  0.40042572
# 234.8  234        A   M var4  0.23404603
# 234.10 234        A   M var5  0.08176435
# 234.12 234        A   M var6  0.02859807

Данные:

set.seed(42)
dat <- expand.grid(id=c(12, 234), location="A", sex="M", time=(1:20)/10)
dat <- cbind(dat, matrix(rnorm(240), 40, 6, dimnames=list(NULL, paste0("var", 1:6))))
dat <- dat[order(dat$id), ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...