R中使用map2或seq函数生成两列间整数序列并转为数据框的问题
问题解决方法
1. 列表列转可保存结构
两种常用实现方案,根据你的使用场景选择:
- 方案1:转成逗号分隔的字符列,可直接保存为csv/tsv等常规表格格式
library(dplyr) library(purrr) # map2_chr直接返回字符向量,而非列表 my.list %>% mutate(new = map2_chr(start, end, ~toString(.x:.y)))
输出的new列示例:第二行值为"3, 4, 5",第五行值为"8, 9, 10, 11, 12"。
- 方案2:展开为长表,每一行对应区间内的一个整数,适合后续做数值计算
my.list %>% mutate(new = map2(start, end, `:`)) %>% tidyr::unnest(new)
输出会把原来的1行拆分为区间长度对应的行数,原有start、end列保留。
2. seq()函数适用性说明
:本身就是seq()针对整数序列的快捷实现,start:end和seq(start, end, by = 1)效果完全一致,纯整数区间场景下用:的执行效率更高,只有需要自定义步长、处理非整数区间的时候才需要显式调用seq()。
3. 大数据量性能优化建议
20万行的数据量级在R中完全可以正常处理,若追求更高性能可选择以下方案:
- R内优化:改用data.table包实现,性能比dplyr+purrr组合高3~5倍,内存占用更低
library(data.table) setDT(my.list) # 转字符列写法 my.list[, new := mapply(function(s,e) toString(s:e), start, end)] # 展开长表写法 my.list[, .(new = start:end), by = .(start, end)]
- Shell实现:如果原始数据为纯文本表格格式,用awk实现的内存占用、执行速度都优于R,适合配置较低的设备使用,示例代码如下(假设输入csv前两列为start、end,带表头):
awk -F ',' 'NR==1{print $0",new"}NR>1{seq="";for(i=$1;i<=$2;i++) seq=seq (seq?",":"") i;print $0","seq}' input.csv > output.csv
内容的提问来源于stack exchange,提问作者Marco Salgado
相关产品推荐
相关产品推荐

