数据框列中列表元素的算术运算问题求解
问题:给数据框中列表列的每个元素添加对应数值,解决长度不匹配问题
我有一个数据框,其中一列是列表类型,需要给列表中的每个数字加上对应行的pep_start数值,但部分列表包含多个元素,导致处理后结果长度与原数据框不匹配。
数据示例
test <- data.frame( "pep_index" = seq(1,6,1), "pep_start" = c(387,8464,33,57,100,7543), "pep_var_mod_pos" = c("000200020002000","00020000","2000000","00000000000","00220000000","000000002") ) test$pep_var_mod_index <- gregexec(pattern="2", test$pep_var_mod_pos) test$pep_var_mod_index[test$pep_var_mod_index=="-1"] <- NA head(test) # pep_index pep_start pep_var_mod_pos pep_var_mod_index # 1 1 387 000200020002000 4, 8, 12 # 2 2 8464 00020000 4 # 3 3 33 2000000 1 # 4 4 57 00000000000 NA # 5 5 100 00220000000 3, 4 # 6 6 7543 000000002 9
尝试过的代码(未得到预期结果)
library(plyr) test$pep_var_mod_res <- ddply(test, c("pep_index"), function(x) unlist(x$pep_var_mod_index) + x$pep_start )
预期输出
# pep_index pep_start pep_var_mod_pos pep_var_mod_index pep_var_mod_res # 1 1 387 000200020002000 4, 8, 12 391, 395, 399 # 2 2 8464 00020000 4 8468 # 3 3 33 2000000 1 34 # 4 4 57 00000000000 NA NA # 5 5 100 00220000000 3, 4 103, 104 # 6 6 7543 000000002 9 7552
解决方案
方法1:Base R的mapply函数
使用mapply逐行配对处理pep_var_mod_index和pep_start,保持结果为列表结构以匹配原数据框行数:
test$pep_var_mod_res <- mapply(function(idx, start) { if (is.na(idx)) { NA } else { unlist(idx) + start } }, test$pep_var_mod_index, test$pep_start, SIMPLIFY = FALSE)
方法2:Tidyverse的purrr::map2函数
如果习惯tidyverse语法,用map2实现相同逻辑:
library(purrr) test$pep_var_mod_res <- map2(test$pep_var_mod_index, test$pep_start, function(idx, start) { if (is.na(idx)) NA else unlist(idx) + start })
运行上述任意一种方法后,查看test即可得到预期的结果。
内容的提问来源于stack exchange,提问作者Yat
相关产品推荐
相关产品推荐

