R语言提取医生间接同事关系 高数值ID适配问题修复
问题根因
代码在高数值医生ID场景失效是R列表索引的默认行为导致的:
- 经
deframe()生成的同事关系存储为命名列表,使用[[x]]提取列表元素时,如果传入的x是数值类型,R默认按元素排列位置做索引,不会匹配列表的名称;只有当x是字符串类型时,才会按列表名称做精准匹配。 - 测试集df1的医生ID是14,刚好和列表内4个元素的位置序号14完全重合,所以运行无异常;测试集df2的医生ID是6~9,调用
[[6]]时R会尝试查找列表的第6个元素,但列表仅存储了4位医生的信息,直接返回空值导致计算中断;字符串类型ID不会触发位置索引逻辑,因此df0运行正常。
修复方案
不需要修改医生原始ID,仅需要在列表索引环节临时将ID转为字符串,强制按名称匹配即可,修复后的完整代码如下:
library(tidyverse) df0 <- tribble( ~hospital, ~doctors, 1, c("a", "b"), 2, c("b", "c"), 3, c("a", "d"), ) %>% unnest(doctors) # 低数值ID测试集 df1 <- tribble( ~hospital, ~doctors, 1, c(1, 2), 2, c(2, 3), 3, c(1, 4), ) %>% unnest(doctors) # 高数值ID测试集 df2 <- tribble( ~hospital, ~doctors, 1, c(6, 7), 2, c(7, 8), 3, c(6, 9) ) %>% unnest(doctors) df <- df2 colleagues <- full_join(df, df, by = c("hospital")) %>% rename(doctor = doctors.x, colleagues = doctors.y) %>% filter(doctor != colleagues) %>% distinct(doctor, colleagues) %>% chop(colleagues) %>% deframe() # 修复点:索引列表时将ID临时转为字符串,强制按名称匹配,不改动原始ID值 result <- colleagues %>% enframe(name = "ego", value = "alter") %>% unnest(alter) %>% mutate(ego_colleagues = map(ego, ~ colleagues[[as.character(.x)]]), alter_colleagues = map(alter, ~ colleagues[[as.character(.x)]]), alter_colleague_only = map2(alter_colleagues, ego_colleagues, ~ .x[!(.x %in% .y)])) %>% unnest(alter_colleague_only) %>% filter(ego != alter_colleague_only) %>% select(ego, alter, alter_colleague_only)
兼容性说明
- 修复逻辑仅在列表索引环节做临时类型转换,结果中医生ID完全保留原始格式,不会被转为字符串
- 对字符串ID、低数值ID、高数值ID三类场景完全兼容,三套测试集均可正确输出间接同事关系
内容的提问来源于stack exchange,提问作者PaulaSpinola
相关产品推荐
相关产品推荐

