【问题标题】:Create a new variable based on modal number of observations根据模态观察数创建一个新变量
【发布时间】:2017-05-17 01:56:56
【问题描述】:

我正在尝试创建一个基于单独变量的观察模型数的新变量。

使用这个df:

help <- data.frame(
id = c(rep(05, times = 8), rep(10, times = 8), rep(12, times = 8)),
episode = c(rep(1, times = 4), rep(2, times =4), rep(3, times = 8), rep(1, times = 4), rep(2, times =4)),
provider = c(rep(70, times = 2), rep(80, times = 2), rep(70, times = 4), rep(30, times = 6), rep(40, times = 2), rep(70, times = 4), rep(10, times = 4)))

我希望创建一个新变量,provider_mode,它基于模式提供者,或者每集观察次数最多的提供者。

最终的 df 看起来像这样:

id episode provider provider_mode
5       1       70       70
5       1       70       70
5       1       80       70
5       1       80       70
5       2       70       70 
5       2       70       70
5       2       70       70
5       2       70       70
10      3       30       30
10      3       30       30
10      3       30       30
10      3       30       30
10      3       30       30
10      3       30       30
10      3       40       30
10      3       40       30
12      1       70       70
12      1       70       70
12      1       70       70
12      1       70       70
12      2       10       10
12      2       10       10
12      2       10       10
12      2       10       10

这是迄今为止我想出的代码,但它只为我提供了每集中每个提供者的计数。我需要创建一个 mutate 命令,将提供者置于最多观察值,如果存在平局,则选择第一个提供者(例如,id 5 中的提供者 70)。

help %>% group_by(id, episode, provider) %>% mutate(provider_count = n()) 

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    使用dplyr,我们可以按idepisode 进行分组,使用table,我们可以找到每个provider 的频率,并使用which.max 选择它的最大值。

    library(dplyr)
    help %>%
      group_by(id, episode) %>%
      mutate(provider_mode = names(which.max(table(provider))))
    
    #     id  episode provider provider_mode
    #   <dbl>   <dbl>    <dbl>         <chr>
    #1      5       1       70            70
    #2      5       1       70            70
    #3      5       1       80            70
    #4      5       1       80            70
    #5      5       2       70            70
    #6      5       2       70            70
    #7      5       2       70            70
    #8      5       2       70            70
    #9     10       3       30            30
    #10    10       3       30            30
    # ... with 14 more rows
    

    类似的可以使用来自基本 R 的ave 实现

    help$provider_mode <- ave(help$provider, help$id, help$episode, FUN = function(x) 
                                          names(which.max(table(x)))) 
    

    【讨论】:

      【解决方案2】:

      问题是 R 并没有真正的 mode() 函数来计算统计模式。我们可以用dplyr() 伪造它,通过计算计数然后将它们合并回来。例如,如果您的数据存储在一个名为dd 的变量中,

      dd %>% 
          group_by(id, episode) %>% 
          count(provider) %>% 
          top_n(1, n) %>% 
          filter(row_number()==1) %>%
          select(-n) %>% 
          rename(provider_mode=provider) %>% 
          right_join(dd)
      

      【讨论】:

      • 我没有意识到top_n 会在出现平局的情况下返回多行。我添加了一个额外的过滤器,每个 id 只返回一个值。
      • 只要我到期group_by(id, episode) 就可以使用...如果我也没有按剧集分组,则 id 12 的提供者在两集中都保持不变。谢谢,轻弹。
      【解决方案3】:

      我们可以创建一个Mode 函数,如here 所示

      Mode <- function(x) {
       ux <- unique(x)
        ux[which.max(tabulate(match(x, ux)))]
      

      }

      然后用data.table,按'id','episode'分组,我们得到'provider'的'Mode'

      library(data.table)
      setDT(help)[, provider_mode := Mode(provider), by = .(id, episode)]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-13
        • 2023-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 1970-01-01
        相关资源
        最近更新 更多