To obtain absolute deviation from the mean for two groups of scores, I usually need to write long codes in R such as the ones shown below.
I was won
How about
score <- lapply(split(y, groups), FUN = function (u) abs(u - mean(u)))
or
score <- ave(y, groups, FUN = function (u) abs(u - mean(u)))
The results are organized in a different way. Choose the one that is most comfortable to you.
There is something wrong with your wording. mad
returns a single statistic / value for data. For example,
sapply(split(y, groups), mad)
You are not vectorizing mad
, but simply computing the deviation for each datum as your example code shows.
If you stick everything in a data.frame, it's much cleaner. In base R,
set.seed(0)
df <- data.frame(y = rnorm(20),
group = rep(1:2, each = 10))
df$abs_dev <- with(df, ave(y, group, FUN = function(x){abs(mean(x) - x)}))
df
#> y group abs_dev
#> 1 1.262954285 1 0.90403032
#> 2 -0.326233361 1 0.68515732
#> 3 1.329799263 1 0.97087530
#> 4 1.272429321 1 0.91350536
#> 5 0.414641434 1 0.05571747
#> 6 -1.539950042 1 1.89887401
#> 7 -0.928567035 1 1.28749100
#> 8 -0.294720447 1 0.65364441
#> 9 -0.005767173 1 0.36469114
#> 10 2.404653389 1 2.04572943
#> 11 0.763593461 2 1.12607477
#> 12 -0.799009249 2 0.43652794
#> 13 -1.147657009 2 0.78517570
#> 14 -0.289461574 2 0.07301974
#> 15 -0.299215118 2 0.06326619
#> 16 -0.411510833 2 0.04902952
#> 17 0.252223448 2 0.61470476
#> 18 -0.891921127 2 0.52943981
#> 19 0.435683299 2 0.79816461
#> 20 -1.237538422 2 0.87505711
or dplyr,
library(dplyr)
set.seed(0)
df <- data_frame(y = rnorm(20),
group = rep(1:2, each = 10))
df <- df %>% group_by(group) %>% mutate(abs_dev = abs(mean(y) - y))
df
#> # A tibble: 20 x 3
#> # Groups: group [2]
#> y group abs_dev
#> <dbl> <int> <dbl>
#> 1 1.262954285 1 0.90403032
#> 2 -0.326233361 1 0.68515732
#> 3 1.329799263 1 0.97087530
#> 4 1.272429321 1 0.91350536
#> 5 0.414641434 1 0.05571747
#> 6 -1.539950042 1 1.89887401
#> 7 -0.928567035 1 1.28749100
#> 8 -0.294720447 1 0.65364441
#> 9 -0.005767173 1 0.36469114
#> 10 2.404653389 1 2.04572943
#> 11 0.763593461 2 1.12607477
#> 12 -0.799009249 2 0.43652794
#> 13 -1.147657009 2 0.78517570
#> 14 -0.289461574 2 0.07301974
#> 15 -0.299215118 2 0.06326619
#> 16 -0.411510833 2 0.04902952
#> 17 0.252223448 2 0.61470476
#> 18 -0.891921127 2 0.52943981
#> 19 0.435683299 2 0.79816461
#> 20 -1.237538422 2 0.87505711
or data.table:
library(data.table)
set.seed(0)
dt <- data.table(y = rnorm(20),
group = rep(1:2, each = 10))
dt[, abs_dev := abs(mean(y) - y), by = group][]
#> y group abs_dev
#> 1: 1.262954285 1 0.90403032
#> 2: -0.326233361 1 0.68515732
#> 3: 1.329799263 1 0.97087530
#> 4: 1.272429321 1 0.91350536
#> 5: 0.414641434 1 0.05571747
#> 6: -1.539950042 1 1.89887401
#> 7: -0.928567035 1 1.28749100
#> 8: -0.294720447 1 0.65364441
#> 9: -0.005767173 1 0.36469114
#> 10: 2.404653389 1 2.04572943
#> 11: 0.763593461 2 1.12607477
#> 12: -0.799009249 2 0.43652794
#> 13: -1.147657009 2 0.78517570
#> 14: -0.289461574 2 0.07301974
#> 15: -0.299215118 2 0.06326619
#> 16: -0.411510833 2 0.04902952
#> 17: 0.252223448 2 0.61470476
#> 18: -0.891921127 2 0.52943981
#> 19: 0.435683299 2 0.79816461
#> 20: -1.237538422 2 0.87505711