在R中创建* NEW *多条件(函数)列

时间:2018-11-13 14:24:44

标签: r conditional mean calculated-columns moving-average

我试图基于两个条件创建一个新的条件列。我想根据名称​​和周(对应行的UP TO(但不包括)周)找到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 :(得分:0)

这是使用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))

答案 1 :(得分:0)

一种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