es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Desviaciones respecto de la media del grupo por ID

Tengo un conjunto de datos en el que el tiempo está anidado dentro de los individuos:

set.seed(124)
x = rnorm(25)
data.frame(id=rep(1:5, each=5), time=1:5, x=x)

¿Cuál sería una solución de base R para agregar una columna que calcule las desviaciones de cada observación desde la media de la misma persona a lo largo del tiempo (es decir, centrando alrededor de la media de la persona)? La salida debería verse así (x.c es la columna agregada que calcula las desviaciones desde la media de la persona):

id time x x.c
1 1 1 -1.38507062 3.814056e-07
2 1 2 0.03832318 1.423394e+00
3 1 3 -0.76303016 6.220408e-01
4 1 4 0.21230614 1.597377e+00
5 1 5 1.42553797 2.810609e+00
6 2 1 0.74447982 2.233398e-08
7 2 2 0.70022940 -4.425040e-02
8 2 3 -0.22935461 -9.738344e-01
9 2 4 0.19709386 -5.473859e-01
10 2 5 1.20715377 4.626740e-01
11 3 1 0.31833673 2.642477e-08
12 3 2 -1.42379885 -1.742136e+00
13 3 3 -0.40509086 -7.234276e-01
14 3 4 0.99538657 6.770499e-01
15 3 5 0.95881779 6.404811e-01
16 4 1 0.91808790 -3.680049e-09
17 4 2 -0.15096960 -1.069058e+00
18 4 3 -1.22306879 -2.141157e+00
19 4 4 -0.86882429 -1.786912e+00
20 4 5 -1.04248536 -1.960573e+00
21 5 1 -1.10363778 2.169331e-07
22 5 2 0.44418506 1.547823e+00
23 5 3 -0.20495061 8.986874e-01
24 5 4 1.67563243 2.779270e+00
25 5 5 -0.13132225 9.723158e-01

Sé que la solución con tidyverse es group_by, pero me gustaría una solución de base R. ¡Gracias!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una solución en base R consiste en calcular primero la media para cada individuo usando tapply, luego usar ave para restar la media individual de cada observación dentro de ese individuo:

    “`{r}

    Calcular las medias individuales

    ind_means <- tapply(x, list(rep(1:5, each=5)), mean)

    Restar la media individual de cada observación

    x.c <- ave(x, rep(1:5, each=5), FUN=function(x) x – ind_means[unique(rep(1:5, each=5))])

    Combinar con los datos originales

    df <- data.frame(id=rep(1:5, each=5), time=1:5, x=x, x.c=x.c)

    Imprimir el resultado

    df


    Esto debería darte el resultado deseado:

    id time x x.c
    1 1 1 0.7013559 1.233369e+00
    2 1 2 -0.7011039 -9.032104e-01
    3 1 3 1.7529302 2.284944e+00
    4 1 4 -0.2309588 -7.899712e-01
    5 1 5 -1.2281187 -1.760133e+00
    6 2 1 0.5256181 5.424853e-01
    7 2 2 -2.3613020 -2.398741e+00
    8 2 3 -0.2132726 5.150513e-01
    9 2 4 -0.1945108 5.732143e-01
    10 2 5 1.2435622 1.281001e+00
    11 3 1 -0.6918348 -1.229647e+00
    12 3 2 0.9867647 1.424913e+00
    13 3 3 -0.8493034 -3.605277e-01
    14 3 4 -1.9869650 -1.325781e+00
    15 3 5 0.0415011 8.670734e-01
    16 4 1 -1.7406439 -1.545736e+00
    17 4 2 -0.3587791 -1.639322e-01
    18 4 3 0.7547053 9.498116e-01
    19 4 4 1.0215622 1.216470e+00
    20 4 5 1.2623268 1.457234e+00
    21 5 1 0.4329204 -7.179256e-01
    22 5 2 -0.2822041 8.166319e-01
    23 5 3 -0.7025074 4.937450e-02
    24 5 4 -0.6792871 7.188099e-02
    25 5 5 0.7037612 -2.605460e-01
    “`

Comments are closed.