如何高效转换data.table嵌套data.frame的列类型以实现合并?
高效展开嵌套data.table并处理列类型不一致问题
先统一嵌套data.frame的列类型
针对fund_metrics列里的每个嵌套data.frame,我们可以批量将列转换为兼容类型,避免rbind时的类型冲突:
手动指定列转换(已知冲突列)
如果明确知道是value列类型不一致(integer/double),直接批量转换:
DT[, fund_metrics := lapply(fund_metrics, function(df) { df$value <- as.double(df$value) df })]
自动检测并统一所有列类型(未知冲突列)
如果不确定哪些列有类型问题,可以自动遍历所有列,将其转换为所有嵌套表中兼容的最高优先级类型:
# 收集所有嵌套表的列名及对应兼容类型 all_cols <- unique(unlist(lapply(DT$fund_metrics, colnames))) col_types <- lapply(all_cols, function(col) { types <- na.omit(sapply(DT$fund_metrics, function(df) if (col %in% colnames(df)) class(df[[col]]) else NA)) if (any(types == "double")) "double" else if (any(types == "integer")) "integer" else types[1] }) names(col_types) <- all_cols # 批量转换每个嵌套表的列 DT[, fund_metrics := lapply(fund_metrics, function(df) { for (col in intersect(colnames(df), names(col_types))) { df[[col]] <- do.call(paste0("as.", col_types[[col]]), list(df[[col]])) } df })]
高效展开合并
类型统一后,直接用data.table的分组rbind操作即可:
final_dt <- DT[, rbindlist(fund_metrics, use.names = TRUE, fill = TRUE), by = .(display_name, reporting_currency)]
use.names=TRUE确保列名匹配fill=TRUE处理部分嵌套表缺少列的情况,自动补NA
替代方案:合并后统一转换
如果不想提前处理嵌套表,也可以先合并再统一类型:
# 先合并所有嵌套表,保留分组标识 temp <- DT[, .(grp_idx = .I, metrics = fund_metrics)] temp <- temp[, rbindlist(metrics, use.names = TRUE, fill = TRUE), by = grp_idx] # 关联原表的分组列并转换类型 final_dt <- temp[DT, on = "grp_idx", .(display_name, reporting_currency, value = as.double(value), metric_name)]
内容的提问来源于stack exchange,提问作者Christoph_J
相关产品推荐
相关产品推荐

