在R中如何匹配指定字符串并将文本拆分生成新行?
报错原因
strsplit对不包含AQUARIUS的行拆分后得到长度为1的列表元素,包含AQUARIUS的行拆分后得到长度为2的列表元素,unlist后总长度大于原数据框的行数,直接绑定原Date、Signs列就会出现行数不匹配的问题。同时你原来的代码没有处理拆分后新行的Signs要替换为AQUARIUS的逻辑。
解决方法
方法1:tidyverse 实现(代码更简洁)
library(dplyr) library(tidyr) library(stringr) result <- horoscopes %>% # 新增临时行标记,用于分组处理 mutate(row_id = row_number()) %>% # 按AQUARIUS拆分Horoscope为多行 separate_rows(Horoscope, sep = "AQUARIUS") %>% # 过滤掉拆分产生的空文本 filter(str_trim(Horoscope) != "") %>% group_by(row_id) %>% # 每个原行的第一部分沿用原星座,第二部分替换为AQUARIUS mutate(Signs = if_else(row_number() == 1, Signs, "AQUARIUS")) %>% ungroup() %>% # 删除临时列 select(-row_id)
方法2:base R 实现(适配你原有代码逻辑)
# 拆分星座文本 h_split <- strsplit(horoscopes$Horoscope, split = "AQUARIUS") # 统计每个原行拆分后的元素个数 split_len <- lengths(h_split) # 按拆分长度重复原列值,匹配unlist后的文本长度 result <- data.frame( Date = rep(horoscopes$Date, split_len), Newspaper = rep(horoscopes$Newspaper, split_len), Horoscope = trimws(unlist(h_split)), # trimws用于去除文本首尾空白 Signs = unlist(mapply(function(ori_sign, len) { if (len == 1) return(ori_sign) c(ori_sign, "AQUARIUS") }, horoscopes$Signs, split_len, SIMPLIFY = FALSE)) )
两种方法都可以适配存在多个AQUARIUS的行,也完全符合你给出的示例输出要求。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

