从R表中的多个列中选择频繁值

时间:2015-06-23 12:22:26

标签: r data.table

我有一个data.table res,其数据如下:

            V1 V2 V3 V4
  1:     Day_1  4  4  4
  2:     Day_2  1  1  2
  3:     Day_3  4  5  4
  4:     Day_4  3  4  4
  5:     Day_5  3  2  3

我需要从列V2,V3和V4中选择最常用的值。也就是说,我需要选择结果如下:

Day_1 4
Day_2 1
Day_3 4
Day_4 4
Day_5 3

我不期待任何联系,因为总会有奇数列。是否可以操纵data.table来执行此操作?或者我应该修改一些其他数据类型吗?

谢谢 - V

3 个答案:

答案 0 :(得分:5)

我将此作为data.tablethis old question发布,直到提供更好的内容

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

DT[, .(res = Mode(unlist(.SD))), by = V1]

#       V1 res
# 1: Day_1   4
# 2: Day_2   1
# 3: Day_3   4
# 4: Day_4   4
# 5: Day_5   3

答案 1 :(得分:3)

以下是David回答的两个变体:

import UIKit
import Parse
class feedTableViewController: UITableViewController {
  var titles = [String]()
  var usernames = [String]()
  var images = [UIImage]()
  var imageFiles = [PFFile]()

  override func viewDidLoad() {
    super.viewDidLoad()
    //....
  }

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var myCell:cell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as cell
    //Error occurs here - does not work due to empty buffer
    myCell.title.text = titles[indexPath.row]
    myCell.username.text = usernames[indexPath.row]
    //If the previous two lines are commented out, I can print out both the arrays
    println(titles)
    println(usernames)

    return myCell
  }
}

我想我会看一下这些因为按行拆分# table DT[,ans:={ tab <- table( r = rep(.I,length(.SD)), unlist(.SD) ) as( colnames(tab)[ max.col(tab) ], class(.SD[[1]]) ) },.SDcols=-1] # apply Mode DT[,ans:=apply(.SD,1,Mode),.SDcols=-1] 可能会很慢。

<强>速度即可。

对行的比较。从很少的唯一值和行开始......

DT

分别增加三个参数中的每一个......

n  <- 1e4
nv <- 5
nc <- 3

DT <- do.call(data.table,c(
  list(id=1:n),
  replicate(nc,sample(nv,n,replace=TRUE),simplify=FALSE)
))

require(rbenchmark)

benchmark(
  table     = DT[,.({
    tab <- table( r = rep(.I,length(.SD)), unlist(.SD) )
    as( colnames(tab)[ max.col(tab) ], class(.SD[[1]]) )
  }),.SDcols=-1],
  byMode    = DT[,.(Mode(unlist(.SD))), by = id],
  applyMode = DT[,.(apply(.SD,1,Mode)),.SDcols=-1],
  replications=10
)[1:5]
#        test replications elapsed relative user.self
# 3 applyMode           10    1.66    4.611      1.65
# 2    byMode           10    2.03    5.639      2.02
# 1     table           10    0.36    1.000      0.36

讨论。 (我正在比较基准测试中的nv <- 1e3 # up from 5 # test replications elapsed relative user.self # 3 applyMode 10 1.67 1.000 1.67 # 2 byMode 10 2.05 1.228 2.02 # 1 table 10 4.27 2.557 4.15 n <- 5e4 # up from 1e4 # test replications elapsed relative user.self # 3 applyMode 10 8.67 4.492 8.65 # 2 byMode 10 10.21 5.290 10.22 # 1 table 10 1.93 1.000 1.92 nc <- 100 # up from 3 # test replications elapsed relative user.self # 3 applyMode 10 2.59 1.000 2.59 # 2 byMode 10 6.71 2.591 6.69 # 1 table 10 11.69 4.514 11.68 列。)

  • nv。虽然elapsed在小案例中胜出,但由于其table对象变得非常大,因此它与唯一值的数量差异很大。其他两种方法不受影响。
  • 名词的。一切都与行数呈线性关系。 (我预计tab在这个方面也会变得更差,但是table可能需要更大。)
  • NC n也会与列呈线性比例,而其他两个表现更好。

再次,融化

table

看起来@ eddi的# back to original values for n, nv, nc benchmark( table = DT[,.({ tab <- table( r = rep(.I,length(.SD)), unlist(.SD) ) as( colnames(tab)[ max.col(tab) ], class(.SD[[1]]) ) }),.SDcols=-1], byMode = DT[,.(Mode(unlist(.SD))), by = id], applyMode = DT[,.(apply(.SD,1,Mode)),.SDcols=-1], melt = melt(DT, id.vars = 'id')[, .N, by = .(id, value)][, value[which.max(N)], by = id], melto = melt(DT, id.vars = 'id')[, .N, by = .(id, value)][ order(N)][,last(value),by=id], meltMode = melt(DT, id.vars = 'id')[,Mode(value),by=id], replications=10 )[1:5] # test replications elapsed relative user.self # 3 applyMode 10 2.42 8.643 2.36 # 2 byMode 10 2.84 10.143 2.81 # 4 melt 10 0.28 1.000 0.28 # 6 meltMode 10 1.92 6.857 1.81 # 5 melto 10 0.44 1.571 0.44 # 1 table 10 0.83 2.964 0.81 melt获胜。

数据

which.max

答案 2 :(得分:3)

转换为长格式,然后执行以下操作:

dt <- data.table(id=paste("Day",1:5,sep="_"),V2=c(4,1,4,3,3),V3=c(4,1,5,4,2),V4=c(4,2,4,4,3))

melt(dt, id.vars = 'id')[, .N, by = .(id, value)][, value[which.max(N)], by = id]
#      id V1
#1: Day_1  4
#2: Day_2  1
#3: Day_3  4
#4: Day_4  4
#5: Day_5  3

这远远快于其他选项,只要唯一(id,value)对的数量不是太大。