【问题标题】:calculate conditional average of a dataframe-vector计算数据帧向量的条件平均值
【发布时间】:2017-04-03 19:25:16
【问题描述】:

我的数据集有以下形式

Name                 year                          val    
”a”                     1                           25    
”a”                     1                           75    
”a”                     2                           20    
”a”                     2                           40    
”a”                     2                           60    
”a”                     3                           50    

”b”                     1                           20    
”b”                     2                           10    
”b”                     2                           20    
”b”                     2                           30
”b”                     3                           40
”b”                     3                           60

所以它由名称年份组成。我想找到每个 yearvalues (val) 的平均值,并按 name 分组。即,我有兴趣获得

Name                  year         average                terms in the average
”a”                     1            50                       2
”a”                     2            40                       3
”a”                     3            NA                       1

”b”                     1            NA                       1
”b”                     2            20                       3
”b”                     3            50                       2

average 列中,只要少于 2 个术语,它就会显示 NA,我还添加了第四列,其中包含平均值中使用的术语数。

这是很多操作,它们自然可以在for-loop 中完成。但是有什么专业的R-方式来解决这样的问题呢?


数据

df = structure(list(name = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), 
    year = c(1, 1, 2, 2, 2, 3, 1, 2, 2, 2, 3, 3), val = c(25, 
    75, 20, 40, 60, 50, 20, 10, 20, 30, 40, 60)), .Names = c("name", 
"year", "val"), row.names = c(NA, -12L), class = "data.frame")

【问题讨论】:

  • name='a' year = 2 的平均值不应该是 40 吗?
  • 您提供的df不是data.frame。

标签: r


【解决方案1】:

dplyr 方式:


library(dplyr)

df %>%
  group_by(name, year) %>% 
  summarize(average = ifelse(n() < 2, NA, mean(val)), 
            `terms in the average` = n())
#> Source: local data frame [6 x 4]
#> Groups: name [?]
#> 
#>     Name  year average `terms in the average`
#>   <fctr> <int>   <dbl>                  <int>
#> 1    ”a”     1      50                      2
#> 2    ”a”     2      40                      3
#> 3    ”a”     3      NA                      1
#> 4    ”b”     1      NA                      1
#> 5    ”b”     2      20                      3
#> 6    ”b”     3      50                      2

【讨论】:

    【解决方案2】:

    data.table 的一种方式:

    library(data.table)
    #group by name and year and calculate average
    df2 <- setDT(df)[, list(average = mean(val), terms = .N), by = c('Name', 'year')]
    #NA if terms less than 2
    df2[terms < 2, average := NA]
    

    输出:

       Name year average terms
    1:    a    1      50     2
    2:    a    2      40     3
    3:    a    3      NA     1
    4:    b    1      NA     1
    5:    b    2      20     3
    6:    b    3      50     2
    

    【讨论】:

    • 你猜对了@Frank。有时我忘记了它是多么简单。谢谢!
    【解决方案3】:
    aggregate(df$val, by = list(df$name, df$year), function(x)
                            c(mean = mean(x)*NA^(!length(x)>1), n = length(x)))
    #  Group.1 Group.2 x.mean x.n
    #1       a       1     50   2
    #2       b       1     NA   1
    #3       a       2     40   3
    #4       b       2     20   3
    #5       a       3     NA   1
    #6       b       3     50   2
    

    【讨论】:

    • OP 想要两个新列:平均值和长度,看起来像。
    猜你喜欢
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多