在R中转换data.table并基于起止位置分配分数
解决方案
可以利用data.table的高效操作实现需求,步骤如下:
- 拆分区间为单个位置:把每行数据的
start到end区间拆成逐个位置,每个位置对应一行,保留id和score。 - 转成宽表格式:将长数据转换为宽表,以
id作为行标识,位置作为列,填充对应的score值。 - 补全列并填充0:确保包含1到10的所有位置列,把未覆盖位置的缺失值替换为0,并调整列顺序。
完整代码
library(data.table) # 示例数据 df <- data.table(id = c(1, 1, 2), start = c(1, 5, 1), end = c(3, 7, 2), score = c(10, 20, 30)) # 拆分区间到单个位置 dt_expanded <- df[, .(pos = seq(start, end)), by = .(id, score)] # 转换为宽表,缺失位置直接填0 result <- dcast(dt_expanded, id ~ pos, value.var = "score", fill = 0) # 补全1-10的所有位置并调整列顺序 all_pos <- 1:10 missing_pos <- setdiff(all_pos, colnames(result)[-1]) if (length(missing_pos) > 0) { result[, (missing_pos) := 0] } setcolorder(result, c("id", all_pos)) # 查看最终结果 result
输出结果
id 1 2 3 4 5 6 7 8 9 10 1: 1 10 10 10 0 20 20 20 0 0 0 2: 2 30 30 0 0 0 0 0 0 0 0
代码说明
df[, .(pos = seq(start, end)), by = .(id, score)]:按id和score分组,生成每组区间内的所有位置,得到长格式数据。dcast(..., fill = 0):转换宽表时,自动将未覆盖位置的单元格填充为0。- 补全列和调整顺序的操作,是为了保证输出包含1到10的全部位置,且列顺序符合要求。
内容的提问来源于stack exchange,提问作者zhang
相关产品推荐
相关产品推荐

