如何按特定条件重组并变换DataFrame,确保PID前缀分组正确?
按PID前缀固定关联列后缀重组DataFrame
原始数据
example <- data.frame( date = as.Date(c('2023-02-12', '2023-02-13', '2023-02-14', '2023-02-12', '2023-02-13', '2023-02-14', '2023-03-06', '2023-03-07', '2023-03-08', '2023-03-07', '2023-03-08', '2023-03-09')), PID = c(1091, 1091, 1091, 2091, 2091, 2091, 1137, 1137, 1137, 2137, 2137, 2137), give = c('a', 'c', 'e', 'aa', 'cc', 'ee', 'aaa', 'ccc', 'eee', 'aaaa', 'cccc', 'eeee'), receive = c('b', 'd', 'f', 'bb', 'dd', 'ff', 'bbb', 'ddd', 'fff', 'bbbb', 'dddd', 'ffff') )
期望输出
example_solution <- data.frame( date = as.Date(c('2023-02-12', '2023-02-13', '2023-02-14', '2023-03-06', '2023-03-07', '2023-03-08', '2023-03-09')), CID = c(91, 91, 91, 137, 137, 137, 137), PID_A = c(1091, 1091, 1091, 1137, 1137, 1137, NA), PID_B = c(2091, 2091, 2091, NA, 2137, 2137, 2137), give_A = c('a', 'c', 'e', 'aaa', 'ccc', 'eee', NA), receive_B = c('bb', 'dd', 'ff', NA, 'bbbb', 'dddd', 'ffff'), give_B = c('aa', 'cc', 'ee', NA, 'aaaa', 'cccc', 'eeee'), receive_A = c('b', 'd', 'f', 'bbb', 'ddd', 'fff', NA) )
现有代码问题
现有代码通过组内顺序生成name列(LETTERS[1:n()]),导致当某日期下仅存在以2开头的PID时,该PID会被错误分配到_A后缀的列,不符合所有以2开头的PID必须关联_B后缀列的核心需求:
example <- example %>% group_by(CID = sub('.', '', PID), date) %>% mutate(name = LETTERS[1:n()]) %>% pivot_wider(values_from = PID:receive) %>% relocate(receive_A, .after = give_B) %>% relocate(receive_B, .after = give_A)
修改后的解决方案
关键修改是根据PID的前缀直接指定name值,而非依赖组内顺序:
example <- example %>% # 提取CID,确保只替换开头第一个字符 mutate(CID = sub('^.', '', PID), # 根据PID开头字符固定分配A/B后缀标识 name = ifelse(substr(as.character(PID), 1, 1) == "1", "A", "B")) %>% group_by(CID, date) %>% pivot_wider(values_from = PID:receive) %>% # 调整列顺序至期望格式 relocate(receive_B, .after = give_A) %>% relocate(receive_A, .after = give_B)
修改说明
- 修正CID提取逻辑:原代码
sub('.', '', PID)会匹配任意单个字符,改为sub('^.', '', PID)确保只替换PID开头的第一个字符,避免意外匹配。 - 固定后缀关联规则:通过
substr提取PID的第一个字符,直接映射为"A"(开头为1)或"B"(开头为2),保证无论组内是否有对应前缀的PID,都能正确关联目标列后缀。 - 保留列顺序调整:沿用原有的
relocate操作,确保最终列顺序与期望输出一致。
内容的提问来源于stack exchange,提问作者jo_
相关产品推荐
相关产品推荐

