Медиана по столбцам с помощью цикла - PullRequest
0 голосов
/ 31 октября 2018

У меня есть данные, касающиеся жителей, разделенных по возрасту в некоторых городах. Другими словами, у меня есть что-то вроде этого

Town        Aged18 Aged19 Aged20 Aged21 Aged22 Aged23 Aged24 Aged25 Total
Rome        2      3      5      10     15     25     20     18     98
Milan       15     19     21     25     25     20     35     15     175
Turin       14     8      8      10     15     25     24     6      110
Florence    10     15     15     10     25     10     5      5      95
Bologna     15     10     25     10     15     10     25     20     130

Я хочу создать новый столбец, в котором указано, в каком столбце «возраст» медиана распределения жителей приходится на каждый город. Другими словами, я хочу создать что-то вроде этого

Town    Aged18 Aged19 Aged20 Aged21 Aged22 Aged23 Aged24 Aged25 Total Median
Rome     2      3      5      10     15     25     20     18     98   23
Milan    15     19     21     25     25     20     35     15     175  22
Turin    14     8      8      10     15     25     24     6      110  22,5
Florence 10     15     15     10     25     10     5      5      95   21
Bologna  15     10     25     10     15     10     25     20     130  22

Строго говоря, я хочу создать цикл, который суммирует содержимое каждого столбца до тех пор, пока мы не достигнем средней позиции, которая, если сумма столбцов нечетная, соответствует (n + 1) / 2, тогда как, если она четная, это соответствует (n / 2 + (n + 1) / 2) / 2. Последний случай относится к Турину в моем кадре данных, где я в среднем составляю от 22 до 23, поскольку они соответствуют столбцам, в которых содержатся соответственно 55-е (110/2) и 56-е (111/2) наблюдения.

Поэтому я хочу, чтобы новый столбец не вычислял медиану по значениям столбцов (что мы можем сделать через rowMedian), но я хочу, чтобы он возвращал столбец (столбцы), который содержит медианное наблюдение.

Может кто-нибудь помочь мне с этим ?? Большое спасибо, я надеюсь, что это может быть полезно даже для кого-то, кто пытается сделать что-то подобное.

1 Ответ

0 голосов
/ 31 октября 2018

Вот подход с использованием Tidyverse.

Сначала я собираю данные в длинную форму, что часто упрощает групповой анализ. Я также конвертирую столбцы Age в числа.

Затем, для каждого Town, я считаю накопленных людей через этот возраст. Мы помечаем строку как соответствующую медиане, если предыдущий совокупный счет был меньше, чем наполовину, но текущий совокупный счет по крайней мере наполовину. Затем мы добавляем корректировку для особого случая, когда итоговое значение является четным, а кумулятивное значение в предыдущей строке равно полпути.

library(tidyverse)
df_long <-
  df %>%
    gather(age, value, Aged18:Aged25) %>%
    mutate(age = str_remove(age, "Aged") %>% as.numeric()) %>%
    arrange(Town, age) %>%  # Probably not necessary but doesn't hurt
    group_by(Town) %>%
    mutate(cuml_count = cumsum(value),
           median     = lag(cuml_count < Total / 2, default = FALSE) & cuml_count >= Total / 2,
           median     = if_else(Total %% 2 == 0 & lag(cuml_count, default = FALSE) == Total / 2, 
                                TRUE, median))

Вот визуальная проверка:

ggplot(df_long, aes(age, cuml_count/Total, color = median)) + geom_point() + facet_wrap(~Town)

enter image description here

Наконец, мы можем объединить исходную таблицу с этими медианами:

df2 <- df %>% 
  left_join(df_long,
            filter(median) %>%
            group_by(Town) %>%
            summarize(median = mean(age)))

Выход:

> df2
      Town Aged18 Aged19 Aged20 Aged21 Aged22 Aged23 Aged24 Aged25 Total median
1     Rome      2      3      5     10     15     25     20     18    98   23.0
2    Milan     15     19     21     25     25     20     35     15   175   22.0
3    Turin     14      8      8     10     15     25     24      6   110   22.5
4 Florence     10     15     15     10     25     10      5      5    95   21.0
5  Bologna     15     10     25     10     15     10     25     20   130   22.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...