R按行处理tibble动态新增列时报「跨组需返回兼容向量」错误如何解决?
错误原因
- 列类型不兼容:不同类别返回的
relevant_field_val系列列数据类型不一致:oncology类的relevant_field_val1为字符型,covid19类的relevant_field_val1为数值型,other类返回的默认值为逻辑型NA,dplyr的mutate要求同一列所有行的数据类型一致,不同类型无法合并就会抛出兼容错误。 - 字典默认值类型不匹配:你给
cat2du_col$get设置的默认值是逻辑型NA,和映射返回的字符向量类型不一致,取值时就会触发强制转换警告。
可行解决方案
方案1:统一列类型,逐行运算绑定结果
修改函数统一返回列的类型,使用purrr::pmap_dfr逐行运行后直接绑定到原数据,代码如下:
library(tidyverse) library(collections) # 初始化字典,默认返回2个字符型NA,避免类型冲突 cat2du_col <- dict() cat2du_col$set('oncology', c('stage', 'is_solid')) cat2du_col$set('covid19', c('saturation', 'is_vaccinated')) # 修改映射函数,统一返回值类型 cat_map <- function(...) { row <- list(...) cols <- cat2du_col$get(row$category, rep(NA_character_, 2)) # 名称列统一为字符型 relevant_field_name1 <- cols[1] relevant_field_name2 <- cols[2] # 值列统一转为字符型避免类型冲突,无需保留原始类型可使用该方案 relevant_field_val1 <- if (!is.na(relevant_field_name1)) as.character(row[[relevant_field_name1]]) else NA_character_ relevant_field_val2 <- if (!is.na(relevant_field_name2)) as.character(row[[relevant_field_name2]]) else NA_character_ return(tibble(relevant_field_name1, relevant_field_val1, relevant_field_name2, relevant_field_val2)) } # 原测试数据 df <- tibble( category = c('oncology', 'covid19', 'other'), stage = c('I', NA, NA), is_solid = c(T, NA, NA), saturation = c(NA, 95, NA), is_vaccinated = c(T, F, T) ) # 逐行运行函数,结果绑定到原数据 df <- bind_cols(df, pmap_dfr(df, cat_map))
方案2:保留val列原始数据类型
如果需要保留val的原始数据类型(数值、逻辑、字符不转成统一字符),可以用list列存储val值:
cat_map <- function(...) { row <- list(...) cols <- cat2du_col$get(row$category, rep(NA_character_, 2)) relevant_field_name1 <- cols[1] relevant_field_name2 <- cols[2] # 值列用list存储,兼容不同数据类型 relevant_field_val1 <- if (!is.na(relevant_field_name1)) list(row[[relevant_field_name1]]) else list(NA) relevant_field_val2 <- if (!is.na(relevant_field_name2)) list(row[[relevant_field_name2]]) else list(NA) return(tibble(relevant_field_name1, relevant_field_val1, relevant_field_name2, relevant_field_val2)) } df <- bind_cols(df, pmap_dfr(df, cat_map))
内容的提问来源于stack exchange,提问作者dimid。
相关产品推荐
相关产品推荐

