Создание * NEW * мультиусловного (функционального) столбца в R - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь создать новый условный столбец на основе двух условий. Я хочу найти среднее значение столбцов A, B и C на основе названия и недель, предшествующих (но не включая), недели в соответствующей строке. Давайте возьмем Джо в качестве примера. Для строки 1 у нас не будет данных в новых столбцах. Для строки 2 будет «среднее» данных за неделю 1. для строки 3 мы хотим получить среднее значение данных недели 1 и недели 2. На практике у нас может быть больше 3 недель, но я хотел упростить пример. Я хотел бы избежать петель , если возможно .

Это довольно легко сделать в Excel с помощью функции Averageifs (), но я хочу автоматизировать / консолидировать процесс с помощью R

мои данные выглядят примерно так:

Name Week A B C
Joe  1    5 6 7
Joe  2    4 5 6
Joe  3    2 3 4
Tim  1    7 8 9
Tim  2    5 4 6 
Tim  4    3 5 4
Bob  1    9 8 7
Bob  3    8 5 2
Bob  4    4 5 3

Новые данные будут выглядеть примерно так:

    Name Week A B C    A_2 B_2 C_2
    Joe  1    5 6 7    NA  NA  NA
    Joe  2    4 5 6    5   6   7
    Joe  3    2 3 4    4.5 5.5 6.5
    Tim  1    7 8 9    NA  NA  NA
    Tim  2    5 4 6    7   8   9
    Tim  4    3 5 4    6   6   7.5
    Bob  1    9 8 7    NA  NA  NA
    Bob  3    8 5 2    9   8   7
    Bob  4    4 5 3    8.5 6.5 4.5

Спасибо за любую помощь, которую вы можете оказать! Я полу новичок в R и борюсь с этой проблемой

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

A data.table подход:

library(data.table)

setDT(df)[order(Name, Week),][, `:=` (
                  A_mean = shift(cummean(A)),
                  B_mean = shift(cummean(B)),
                  C_mean = shift(cummean(C))
                  ), by = Name][]

Обратите внимание, что [] в конце только для печати результата.

Вывод:

   Name Week A B C A_mean B_mean C_mean
1:  Bob    1 9 8 7     NA     NA     NA
2:  Bob    3 8 5 2    9.0    8.0    7.0
3:  Bob    4 4 5 3    8.5    6.5    4.5
4:  Joe    1 5 6 7     NA     NA     NA
5:  Joe    2 4 5 6    5.0    6.0    7.0
6:  Joe    3 2 3 4    4.5    5.5    6.5
7:  Tim    1 7 8 9     NA     NA     NA
8:  Tim    2 5 4 6    7.0    8.0    9.0
9:  Tim    4 3 5 4    6.0    6.0    7.5
0 голосов
/ 13 ноября 2018

Вот способ с пакетом dplyr -

df %>%
  group_by(Name) %>% 
  arrange(Name, Week) %>% 
  mutate(
    A_2 = lag(cummean(A)),
    B_2 = lag(cummean(B)),
    C_2 = lag(cummean(C))
  ) %>% 
  ungroup()

# A tibble: 9 x 8
  Name   Week     A     B     C   A_2   B_2   C_2
  <fct> <int> <int> <int> <int> <dbl> <dbl> <dbl>
1 Bob       1     9     8     7 NA    NA    NA   
2 Bob       3     8     5     2  9.00  8.00  7.00
3 Bob       4     4     5     3  8.50  6.50  4.50
4 Joe       1     5     6     7 NA    NA    NA   
5 Joe       2     4     5     6  5.00  6.00  7.00
6 Joe       3     2     3     4  4.50  5.50  6.50
7 Tim       1     7     8     9 NA    NA    NA   
8 Tim       2     5     4     6  7.00  8.00  9.00
9 Tim       4     3     5     4  6.00  6.00  7.50

Данные -

df <- structure(list(Name = structure(c(2L, 2L, 2L, 3L, 3L, 3L, 1L, 
1L, 1L), .Label = c("Bob", "Joe", "Tim"), class = "factor"), 
    Week = c(1L, 2L, 3L, 1L, 2L, 4L, 1L, 3L, 4L), A = c(5L, 4L, 
    2L, 7L, 5L, 3L, 9L, 8L, 4L), B = c(6L, 5L, 3L, 8L, 4L, 5L, 
    8L, 5L, 5L), C = c(7L, 6L, 4L, 9L, 6L, 4L, 7L, 2L, 3L)), .Names = c("Name", 
"Week", "A", "B", "C"), class = "data.frame", row.names = c(NA, 
-9L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...