You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R data.table无循环实现函数赋值与连接赋值?

用data.table实现无循环的层级聚类赋值与连接赋值

1. 按ID分组生成层级聚类对象(替代第一个for循环)

你原来通过for循环给tSummary的Clust列赋值层级聚类对象,完全可以用data.table的原生分组操作实现,不需要循环:

解决方案代码

library(data.table)

# 生成示例数据
tAmounts <- data.table(
  rbind(
    cbind(ID="Apple", Amt=as.numeric(EuStockMarkets[1:50,2])),
    cbind(ID="Orange", Amt=as.numeric(EuStockMarkets[1:30,3])),
    cbind(ID="Lemon", Amt=as.numeric(EuStockMarkets[1:60,4]))
  )
)
setkey(tAmounts, ID, Amt)

# 直接按ID分组生成聚类对象,无需循环
tSummary <- tAmounts[, .(
  N = .N,
  Clust = list(hclust(dist(Amt), method = "average"))
), by = ID]

说明

data.table的by分组会对每个ID组独立计算j中的表达式:

  • .N直接返回每组的行数
  • 用list()包裹hclust(dist(Amt), ...),是因为hclust返回的是一个对象,需要将其作为列表元素存入Clust列,确保每个组对应一个聚类对象。

你提到的类似tSummary[, Clust:=hclust(dist(Amt), method="average"), by="ID"]的写法,需要调整为用list()包裹hclust调用,否则会因对象长度不匹配报错,正确的修改写法是:

# 如果是对已存在的tSummary表修改
tSummary <- tAmounts[, .(N = .N), by = ID]
tSummary[, Clust := list(hclust(dist(tAmounts[ID == .BY$ID]$Amt), method = "average")), by = ID]

2. 连接操作中基于聚类对象生成分组编号(替代第二个for循环)

你原来通过循环tCuts的每一行给tClust赋值ClustNum,可以用data.table的连接+分组操作实现无循环赋值:

解决方案代码

# 生成切割高度表
tCuts <- CJ(ID=unique(tAmounts$ID), Cut=seq(20,100,20))
setkey(tCuts, ID, Cut)

# 生成包含所有ID-Cut-Amt组合的表
tClust <- tCuts[tAmounts, on="ID", allow.cartesian=TRUE]
setkey(tClust, ID, Cut, Amt)

# 无循环赋值ClustNum
tClust[, ClustNum := cutree(tSummary[ID == .BY$ID]$Clust[[1]], h = .BY$Cut), by = .(ID, Cut)]

说明

  • .BY是data.table分组中的特殊变量,代表当前组的键值(这里是ID和Cut的组合)
  • 对每个ID-Cut组,从tSummary中取出对应ID的聚类对象,用当前组的Cut值作为cutree的高度参数,直接生成该组所有Amt对应的聚类编号。

如果你想更贴近你提到的tClust[tCuts, ClustNum:=cutree(Clust, h=Cut)]写法,可以用**连接+by=.EACHI**实现:

# 先将聚类对象关联到tCuts
tCuts_with_clust <- tCuts[tSummary, on = "ID"]

# 通过连接+逐组计算赋值
tClust[, ClustNum := tCuts_with_clust[.SD, 
  cutree(Clust[[1]], h = Cut), 
  by = .EACHI, 
  on = .(ID, Cut)]$V1]

by=.EACHI会针对tCuts_with_clust中的每个ID-Cut组合,匹配tClust中对应的行并计算聚类编号。


内容的提问来源于stack exchange,提问作者C8H10N4O2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:50:37