在 tidyverse 中命名融化的迭代映射列表
naming melted iteratively mapped lists in the tidyverse
我经常在循环中做循环,然后最后将列表融化为数据框以进行绘图。
ac<-list("BB","AA")
ca<-list(a=c(1,2,3),b=c(6,5,4))
cc<-map(a,function(y) map(ca,~paste0(.x,y)))
reshape2::melt(cc)
问题 1:是否有另一种方法可以在不借助 function(y)
的情况下在地图内部制作地图
但是,由于我的列表通常是未命名的,所以我倾向于将列表的值添加为名称,如下所示:
map_test<-function(list_in,...){
if (is.null(names(list_in))){
names(list_in)<-list_in
}
map(list_in,...)
}
cc2=map_test(ac,function(y) map_test(ca,~paste0(.x,y)))
df=reshape2::melt(cc2)
生成的 df 的名称为 L2 和 L1,如果名称分别为 ca 和 ac,我会更喜欢。
nam.cons<-NULL
map_test2<-function(list_in,...){
nam.cons<<-c(nam.cons,deparse(substitute(list_in)))
if (is.null(names(list_in))){
names(list_in)<-list_in
}
map(list_in,...)
}
cc3=map_test2(ac,function(y) map_test2(ca,~paste0(.x,y)))
cc4<-reshape2::melt(cc3)
names(cc4)<-c("value",rev(unique(nam.cons)))
如果我忘记重置 nam.cons
变量,这很快就会变得混乱。我可以在不同的函数中创建 1,2,3,4..n 版本,但是
问题 2:是否可以创建 one melt_map 函数,允许两者都接受循环遍历 n 个不同的列表,并且最后还保留 n -不同的列表名称作为列名?
我们想要优雅地遍历列表项的每个组合,而不丢失我们的列表名称。
所以让我们构建所有组合并存储名称:
library(tidyverse) # data
ac<-list("BB","AA") #
ca<-list(a=c(1,2,3),b=c(6,5,4)) #
df <- merge(tibble(ac),tibble(ca))
# ac ca
# 1 BB 1, 2, 3
# 2 AA 1, 2, 3
# 3 BB 6, 5, 4
# 4 AA 6, 5, 4
然后我们就可以开始玩了,并以整洁的方式轻松地做我们想做的事情,而无需重复使用地图和替代调用,例如:
df %>%
mutate(ac=unlist(ac),
name =names(ca)) %>%
unnest %>%
mutate(value = paste0(ca,ac))
# ac name ca value
# 1 BB a 1 1BB
# 2 BB a 2 2BB
# 3 BB a 3 3BB
# 4 AA a 1 1AA
# 5 AA a 2 2AA
# 6 AA a 3 3AA
# 7 BB b 6 6BB
# 8 BB b 5 5BB
# 9 BB b 4 4BB
# 10 AA b 6 6AA
# 11 AA b 5 5AA
# 12 AA b 4 4AA
我经常在循环中做循环,然后最后将列表融化为数据框以进行绘图。
ac<-list("BB","AA")
ca<-list(a=c(1,2,3),b=c(6,5,4))
cc<-map(a,function(y) map(ca,~paste0(.x,y)))
reshape2::melt(cc)
问题 1:是否有另一种方法可以在不借助 function(y)
但是,由于我的列表通常是未命名的,所以我倾向于将列表的值添加为名称,如下所示:
map_test<-function(list_in,...){
if (is.null(names(list_in))){
names(list_in)<-list_in
}
map(list_in,...)
}
cc2=map_test(ac,function(y) map_test(ca,~paste0(.x,y)))
df=reshape2::melt(cc2)
生成的 df 的名称为 L2 和 L1,如果名称分别为 ca 和 ac,我会更喜欢。
nam.cons<-NULL
map_test2<-function(list_in,...){
nam.cons<<-c(nam.cons,deparse(substitute(list_in)))
if (is.null(names(list_in))){
names(list_in)<-list_in
}
map(list_in,...)
}
cc3=map_test2(ac,function(y) map_test2(ca,~paste0(.x,y)))
cc4<-reshape2::melt(cc3)
names(cc4)<-c("value",rev(unique(nam.cons)))
如果我忘记重置 nam.cons
变量,这很快就会变得混乱。我可以在不同的函数中创建 1,2,3,4..n 版本,但是
问题 2:是否可以创建 one melt_map 函数,允许两者都接受循环遍历 n 个不同的列表,并且最后还保留 n -不同的列表名称作为列名?
我们想要优雅地遍历列表项的每个组合,而不丢失我们的列表名称。
所以让我们构建所有组合并存储名称:
library(tidyverse) # data
ac<-list("BB","AA") #
ca<-list(a=c(1,2,3),b=c(6,5,4)) #
df <- merge(tibble(ac),tibble(ca))
# ac ca
# 1 BB 1, 2, 3
# 2 AA 1, 2, 3
# 3 BB 6, 5, 4
# 4 AA 6, 5, 4
然后我们就可以开始玩了,并以整洁的方式轻松地做我们想做的事情,而无需重复使用地图和替代调用,例如:
df %>%
mutate(ac=unlist(ac),
name =names(ca)) %>%
unnest %>%
mutate(value = paste0(ca,ac))
# ac name ca value
# 1 BB a 1 1BB
# 2 BB a 2 2BB
# 3 BB a 3 3BB
# 4 AA a 1 1AA
# 5 AA a 2 2AA
# 6 AA a 3 3AA
# 7 BB b 6 6BB
# 8 BB b 5 5BB
# 9 BB b 4 4BB
# 10 AA b 6 6AA
# 11 AA b 5 5AA
# 12 AA b 4 4AA