我在列表中有data.frame对象,这些对象也以所需的方式进行操作以进行进一步处理。但是,我打算将每个列表的补充集给定条件,我也只是简单地绘制辅助函数来执行此任务。我使用dplyr包中的setdiff函数,我敢打赌这是正确的方法。但输出结果不是我的预期。我尝试了一种使用辅助函数进行嵌套列表的可能方法,但是如果我更改了参数(type = c(“Bio”,“Tech”)),则输出不正确。有没有快速的方法来获得我期望的干净,结构良好的输出?我怎样才能做到这一点?有什么想法吗?
快速可重复的例子:
savedList <- list(
foo_saved = data.frame(v1=c(1,6,16), v2=c(4,12,23), nm=c("a1","a2","a3")),
bar_saved = data.frame(v1=c(7,19,31), v2=c(13,28,43), nm=c("b3","b6","b7")),
cat_saved = data.frame(v1=c(5,21,36), v2=c(11,29,42), nm=c("c2","c4","c9"))
)
dropedList <- list(
foo_droped = data.frame(v1=c(6,25,40), v2=c(12,33,49),nm=c("a2","a5","a8")),
bar_droped = data.frame(v1=c(15,19,47), v2=c(18,28,55),nm=c("b4","b6","b9")),
cat_droped = data.frame(v1=c(13,21,36,53), v2=c(19,29,42,67),nm=c("c3","c4","c9","c12"))
)
我用这个技巧来操纵列表:
x <- c(savedList, dropedList)
newList <- split(x, sub("_.*", "", names(x)))[sub("_.*", "", names(savedList))]
这是我打算实现的辅助函数:
func <- function(list, type=c("Bio", "Tech")) {
type=match.arg(type)
if(type=="Bio") list[[1]] else setdiff(list[[1]], list[[2]])
}
我这样做可能实现我的输出:
res <- Map(func, newList)
但如果我将类型设置为“Tech”,则此功能无效,setdiff无法返回我预期的补充设置。如果我使用Map,更改类型并获得不同的输出也有点困难。有没有有效的方法来获得我想要的输出?
然后我想有条件地对每个列表进行补充。
如果类型为“Bio”,则需要输出:
output.Bio <- list(
foo_otp = data.frame(v1=c(1,6,16), v2=c(4,12,23), nm=c("a1","a2","a3")),
bar_otp = data.frame(v1=c(7,19,31), v2=c(13,28,43), nm=c("b3","b6","b7")),
cat_otp = data.frame(v1=c(5,21,36), v2=c(11,29,42), nm=c("c2","c4","c9"))
)
如果type为“Tech”,则需要输出:
output.Tech <- list(
foo_otp = data.frame(v1=c(1,16),v2=c(4,23),nm=c("a1","a3")),
bar_otp = data.frame(v1=c(7,31),v2=c(13,43),nm=c("b3","b7")),
cat_otp = data.frame(v1=c(5),v2=(11),nm="c2")
)
我无法弄清楚辅助函数出了什么问题。有什么建议可以确保帮助函数以更安全的方式工作吗?如何才能完成此任务以更有效地获得所需的输出?非常感谢
答案 0 :(得分:1)
您正在研究data.frame
之间的区别,anti_join
来自dplyr
的{{1}}。这将为您提供output.Tech
:
Map(anti_join, savedList, dropedList)
#Joining by: c("v1", "v2", "nm")
#Joining by: c("v1", "v2", "nm")
#Joining by: c("v1", "v2", "nm")
#$foo_saved
# v1 v2 nm
#1 16 23 a3
#2 1 4 a1
#$bar_saved
# v1 v2 nm
#1 7 13 b3
#2 31 43 b7
#$cat_saved
# v1 v2 nm
#1 5 11 c2
如果您想将这段代码合并到您的代码中,只需创建一个简单的函数:
func = function(L1, L2, type)
{
if(!type %in% c('Bio','Tech')) stop('Wrong type')
if(type=='Bio') return(L1)
Map(anti_join, L1, L2)
}
#func(savedList, dropedList, 'Tech')
#func(savedList, dropedList, 'Bio')