【问题标题】:data.matrix() when character involved涉及字符时的 data.matrix()
【发布时间】:2012-09-10 08:58:25
【问题描述】:

为了计算每个 ID 的行的最大贡献,我有一个漂亮的脚本,当 ID 是数字时它可以工作。然而,今天我发现 ID 也可能有字符(例如 ABC10101)。为了使函数起作用,数据集被转换为矩阵。但是data.matrix(df) 不支持字符。是否可以更改代码以使函数与各种 ID(字符、数字等)一起使用?目前,我编写了一个快速解决方法,当 ID=character 时将 ID 转换为数字,但这会减慢大型数据集的处理速度。

代码示例(功能:提取贡献最高的第一个条目,因此如果两个条目具有相同的贡献,则选择第一个):

注意:在此示例中,ID 被解释为一个因子,data.matrix() 将其转换为数值。在下面的代码中,ID 列的类型应为字符,输出应如底部所示。订单 ID 必须保持不变。

tc <- textConnection('
    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022221       40           102 
   ABCUD022222       20           103
   ABCUD022222       10           104
   ABCUD022222       90           105
   ABCUD022223       75           106
   ABCUD022223       15           107
   ABCUD022223       10           108        ')

df <- read.table(tc,header=TRUE)

#Function that needs to be altered
uniqueMaxContr <- function(m, ID = 1, contribution = 2) {
  t(
    vapply(
           split(1:nrow(m), m[,ID]), 
           function(i, x, contribution) x[i, , drop=FALSE]
           [which.max(x[i,contribution]),], m[1,], x=m, contribution=contribution
          )
  )
}

df<-data.matrix(df) #only works when ID is numeric
highestdf<-uniqueMaxContr(df)
highestdf<-as.data.frame(highestdf)

在这种情况下,结果应该是:

    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022222       90           105
   ABCUD022223       75           106

【问题讨论】:

  • 为什么需要data.matrix?纯粹是为了尺寸限制?如果这是真的,我觉得“先生。data.table 解决方案”正潜伏在阴影中。 @mnel? :)
  • 我真的没有任何限制,所以 data.table 是一个选项。

标签: r matrix character data.table


【解决方案1】:

其他人可能会使其更简洁,但这是我对 data.table 解决方案的尝试:

tc <- textConnection('
    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022221       40           102 
   ABCUD022222       20           103
   ABCUD022222       10           104
   ABCUD022222       90           105
   ABCUD022223       75           106
   ABCUD022223       15           107
   ABCUD022223       10           108        ')

df <- read.table(tc,header=TRUE)

library(data.table)
dt <- as.data.table(df)
setkey(dt,uniqID)

dt2 <- dt[,list(contribution=max(contribution)),by=ID]

setkeyv(dt2,c("ID","contribution"))
setkeyv(dt,c("ID","contribution"))

dt[dt2,mult="first"]

##               ID contribution uniqID
## [1,] ABCUD022221           40    101
## [2,] ABCUD022222           90    105
## [3,] ABCUD022223           75    106

编辑——更简洁的解决方案

  • 您可以使用.SD,它是data.table 的子集进行分组,然后使用which.max 提取单行。

一行

dt[,.SD[which.max(contribution)],by=ID]

##               ID contribution uniqID
## [1,] ABCUD022221           40    101
## [2,] ABCUD022222           90    105
## [3,] ABCUD022223           75    106

【讨论】:

  • 让它更简洁一点。 -- 不需要合并。
  • data.table 这么强大,但它确实需要一个语法前端。
  • 花足够的时间使用它,它开始变得有意义。阅读@MatthewDowle 对 SO 的回答和编辑——这就是我的学习方式!
  • 我知道像这样学习 data.table 是可能的,这就是我正在做的事情,但是你需要花费这么多精力并不是最优的。初学者的门槛很高。
  • @Roland 常见任务 wiki 能否提供帮助,显示各种任务的语法?我们目前最接近的是example(data.table)。 ?data.table 顶部的提示建议在提示符下运行 example(data.table) 并完成它。你这样做了吗?你读过所有 3 个小插曲吗?常见问题解答的第一部分应按顺序阅读。 data.table 并不是要从 S.O. 学习,我同意!当您说学习需要付出很多努力时,您到目前为止花了多长时间?有兴趣了解更多有关您的学习经历的信息,以便我们改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多