【问题标题】:Mode in R by groupsR中的模式按组
【发布时间】:2014-11-05 14:43:20
【问题描述】:

我需要为每个年龄组计算一个身份号码的众数。让我们假设下表:

library(data.table)
DT = data.table(age=c(12,12,3,3,12),v=rnorm(5), number=c("122","125","5","5","122"))

所以我创建了一个函数:

g <- function(number) {
      ux <- unique(number)
      ux[which.max(tabulate(match(number, ux)))]
    }
H<-function(tabla){data.frame(MODA=g, count=nrow(tabla))}
clasif_edad1<-ddply(DF,.(age), H)
View(clasif_edad1)

但我得到以下错误:

Error: arguments imply differing number of rows: 0, 1

输出应该是:

age      v    number moda
12  0,631152199 122 122
12  0,736648714 125 122
3   0,545921527 5   5
3   0,59336284  5   5
12  0,836685437 122 122

不知道是什么问题。

谢谢

【问题讨论】:

  • 你的功能有点不清楚。你能显示你想要的输出吗?同样,没有任何理由将data.table 转换为data.frame,然后使用plyrdata.table 是 R 之王,按原样使用
  • 如果你想让我们重现你的专栏v,你需要使用set.seed,因为rnorm每次运行都会生成一个随机种子

标签: r function mode


【解决方案1】:

一种方法:

> myfun <- function(x) unique(x)[which.max(table(x))]
> DT[ , moda := myfun(number), by = age]
> DT
   age          v number moda
1:  12 -0.9740026    122  122
2:  12  0.6893727    125  122
3:   3 -0.9558391      5    5
4:   3 -1.2317071      5    5
5:  12 -0.9568919    122  122

【讨论】:

  • 这似乎是使用data.table 的惯用方式。
  • 我正在处理大约 4MM 行的数据,这需要很长时间才能运行 - 按组查找 ~4 个值的模式增加了我创建所需的时间一个新的数据表,其中约 10 个其他变量乘以 6 倍。有没有办法更有效地找到模式?现在我的计划是要么减少采样,要么让程序在一夜之间运行。
  • @verybadatthis 我想R中没有更快的方法,
  • 实际上,我写完这篇文章后,found a somewhat faster way detailed here 和你在这里做的很相似,只是稍微矢量化和分裂了。
【解决方案2】:

您可以为此使用dplyr

library(dplyr)
modes_by_age <- summarise(group_by(DT, age), group_mode = g(number))
inner_join(DT, modes_by_age)

这给出了你想要的输出:

Source: local data table [5 x 4]

  age         v number group_mode
1   3 0.5524352      5          5
2   3 0.2869912      5          5
3  12 0.8987475    122        122
4  12 0.9740715    125        122
5  12 2.5058450    122        122

【讨论】:

    【解决方案3】:

    这是一个基本的 R 解决方案。您可以计算每个组的模式,然后与原始数据合并:

    merge(DT, setNames(aggregate(number~age, data=DT, g), c("age", "moda")), by="age")
    #    age          v number moda
    # 1:   3  1.7148357      5    5
    # 2:   3  0.9504811      5    5
    # 3:  12 -0.7648237    122  122
    # 4:  12  0.9011115    125  122
    # 5:  12 -0.8718779    122  122
    

    可能有一种特定于数据表的方法,但即使 DT 是一个数据框,它也可以工作。

    【讨论】:

      【解决方案4】:
      modef <- function(V)
      { 
      k = 1
      prev='xxxx'
      max_value = 0
      for (i in V)
      {
      if (prev == i)
      { 
      k = k+1
      }
      else
      {
      if (k > max_value) 
      {
      MODE_CALC = data.frame( 
      number = c(prev) , 
      occurence = c(k) )
      max_value = k
      k = 1
      }
      k = 1
      }
      prev = i
      }
      print(MODE_CALC$number)
      }
      V = c(11, 11, 11, 11, 12, 12, 2, 2, 2, 2, 2, 2, 14, 14, 14, 15, 16, 17, 17, 17 ,17 , 
      17, 18, 19)    
      modef(sort(V))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 2016-11-08
        • 2021-07-03
        • 2020-12-19
        • 2015-08-03
        相关资源
        最近更新 更多