如何用dplyr拆分Event列,将每个事件转为单独行并生成新列?
事件拆分与列提取解决方案
原始数据
| MatchID | Player | Event |
|---|---|---|
| 1096 | Marcel | NA |
| 1096 | Juan | G70'IO85' |
| 1090 | Andre | P43'G87' |
需求目标
将Event列中的每个事件拆分为单独行,提取事件类型(字母部分,如G、IO)和事件时间(数字部分,如70、85);若Event为NA,对应新列也保留NA,最终结果如下:
| MatchID | Player | Event_type | Event_time |
|---|---|---|---|
| 1096 | Marcel | NA | NA |
| 1096 | Juan | G | 70 |
| 1096 | Juan | IO | 85 |
| 1090 | Andre | P | 43 |
| 1090 | Andre | G | 87 |
问题分析
你当前使用str_match_all仅能在同一行生成列表格式的结果,无法将多事件拆分为单独行。需要结合列表列展开和精准正则匹配来实现需求。
实现代码
library(dplyr) library(tidyr) library(stringr) df %>% # 提取每个独立事件单元(如G70'、IO85'),生成列表列 mutate(events = str_extract_all(Event, "[A-Z]+[0-9]+'")) %>% # 将列表列展开为多行,保留NA行 unnest_longer(events, keep_empty = TRUE) %>% # 从事件单元中分别提取类型和时间 mutate( Event_type = str_match(events, "([A-Z]+)[0-9]+'")[, 2], Event_time = as.integer(str_match(events, "[A-Z]+([0-9]+)'")[, 2]) ) %>% # 保留目标列 select(MatchID, Player, Event_type, Event_time)
代码说明
str_extract_all(Event, "[A-Z]+[0-9]+'"):用正则匹配每个由大写字母、数字、单引号组成的独立事件,将同一单元格的多个事件转为列表。unnest_longer(events, keep_empty = TRUE):把列表列展开为单独行,keep_empty=TRUE确保原始NA的行不被过滤。str_match(...):通过正则捕获组分别提取事件类型(字母部分)和事件时间(数字部分),时间转为整数类型保证数据格式正确。select:移除中间辅助列,保留最终需要的字段。
内容的提问来源于stack exchange,提问作者GitZine
相关产品推荐
相关产品推荐

