R语言中如何创建新函数迭代已有函数生成完整《十二天圣诞节》歌曲
问题原因分析
- 第一个报错是因为
sing_verse函数返回的是长度和输入num相等的glue向量,而map_chr要求每轮迭代返回单个长度为1的字符串,类型不匹配导致报错。 - 第二个报错是因为
cat()函数的返回值是NULL,把glue放到cat里后sing_verse没有有效字符串返回,map_chr拿到NULL自然报错。
代码修改方案
首先确保提前加载依赖包:
library(english) library(glue) library(purrr)
1. 调整sing_verse函数
把单段歌词的所有内容(包括开头的固定句式)拼接成单个字符串返回,不要拆分输出:
sing_verse <- function(num, day, gift) { current_day <- day[num] daily_phrase <- make_phrase(num:1, gift[num:1]) # 可选优化:适配原版歌曲规则,多礼物时最后一个礼物前加and if(num > 1) daily_phrase[length(daily_phrase)] <- paste0("and ", daily_phrase[length(daily_phrase)]) # 拼接整段歌词为单个字符串,短语用换行分隔 full_verse <- glue( "On the {current_day} day of Christmas, my true love gave to me, {paste(daily_phrase, collapse = '\n')}" ) return(as.character(full_verse)) }
2. 调整sing_xmas_song函数
不需要强制用map_chr,直接迭代输出或者拼接所有段落即可:
sing_xmas_song <- function(days = 1:12, day_names, gift_list) { all_verses <- map(days, ~sing_verse(.x, day_names, gift_list)) # 段落之间加空行分隔,直接输出 cat(paste(all_verses, collapse = "\n\n")) # 可选:返回完整歌词字符串方便后续处理 invisible(paste(all_verses, collapse = "\n\n")) }
调用示例
假设你已经构造好了xmas数据集,直接调用即可:
# 示例xmas数据集构造(已有数据集可跳过) xmas <- data.frame( day_in_words = c("first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth"), gift_item = c("partridge in a pear tree", "turtle doves", "French hens", "calling birds", "gold rings", "geese a-laying", "swans a-swimming", "maids a-milking", "ladies dancing", "lords a-leaping", "pipers piping", "drummers drumming") ) # 生成完整歌曲 sing_xmas_song(day_names = xmas$day_in_words, gift_list = xmas$gift_item)
内容的提问来源于stack exchange,提问作者Alijah Maldonado
相关产品推荐
相关产品推荐

