使用回收的矢量元素将R列表转换为数据帧
我已经有一段时间没有在R工作了,所以我有点生疏了,需要一些列表方面的帮助。我有一个列表,其中包含7个与顾客在参观大型连锁店时购买的物品有关的元素(下面提供了列表的一个片段)。在给定索引中,元素1、2和7始终是长度为1的向量,而元素4、5和6始终是长度相同的向量,但因列表索引而异(例如,从[[74]]到[[75]])。这是因为元素1、2和7是关于顾客对商店的访问,而元素4、5和6是关于他们在访问期间的个人购买,因此元素1、2、7(访问)和3、4和5(购买)之间存在一对多关系。我正在尝试找出如何有效地将列表转换为单个数据帧。问题是,当我创建一个大型数据框架时,访问信息可以在列表索引中的购买中循环使用。例如,在下面提供的示例数据中,我希望订单号、日期、付款方式(“Visa”)可以在数据框中的每个购买中循环使用,因此最终看起来如下所示:使用回收的矢量元素将R列表转换为数据帧,r,list,dataframe,multidimensional-array,lapply,R,List,Dataframe,Multidimensional Array,Lapply,我已经有一段时间没有在R工作了,所以我有点生疏了,需要一些列表方面的帮助。我有一个列表,其中包含7个与顾客在参观大型连锁店时购买的物品有关的元素(下面提供了列表的一个片段)。在给定索引中,元素1、2和7始终是长度为1的向量,而元素4、5和6始终是长度相同的向量,但因列表索引而异(例如,从[[74]]到[[75]])。这是因为元素1、2和7是关于顾客对商店的访问,而元素4、5和6是关于他们在访问期间的个人购买,因此元素1、2、7(访问)和3、4和5(购买)之间存在一对多关系。我正在尝试找出如何有效
73 "Order #: 065-PO-4080219" "Sunday, September 17 2017" "PowerColor Red Dragon Radeon RX 580 Dual-Fan 8GB GDDR5 PCIe Video Card" $329.99 1 "Visa"
73 "Order #: 065-PO-4080219" "Sunday, September 17 2017" "PowerColor Red Dragon Radeon RX 580 Dual-Fan 8GB GDDR5 PCIe Video Card" $329.99 1 "Visa"
73 "Order #: 065-PO-4080219" "Sunday, September 17 2017" "ASUS PRIME Z270-AR LGA 1151 ATX Intel Motherboard" $159.99 1 "Visa"
74 "Order #: 065-PO-4079152" "Saturday, September 16 2017" "Olympia Tools Tool Set 53 Piece" $12.99 1 "Visa"
74 "Order #: 065-PO-4079152" "Saturday, September 16 2017" "The Best Connection Cable Ties" $1.99 1 "Visa"
我已经能够通过首先将每个列表索引转换为数据帧,然后使用:
do.call("rbind", MyListOfDataFrames)
但对我来说,这似乎真的很低效(据我所知,首先转换为数据帧,然后将它们组合成更大的数据帧通常是低效的)
有没有办法将此列表转换为一个大数据帧?我有成千上万的这些记录要处理,所以我希望尽可能提高效率。如果有帮助的话,我已经将数据的一小部分放在了一个可供下载的公开网站上(可以使用load()
函数加载,生成的列表称为ProductList
,我已经使用dput()放置了列表的ASCII表示形式)
根据用户的建议,我还将原始的dput()
输出放在本文末尾)。我试着搜索stackoverflow上的帖子,但似乎没有一个能真正解决这个问题。谢谢你的帮助
列表片段
[[73]][[1]]
[1] 73
[73]][[2]]
[1] "Order #: 065-PO-4080219"
[[73]][[3]]
[1] "Sunday, September 17 2017"
[[73]][[4]]
[1] "PowerColor Red Dragon Radeon RX 580 Dual-Fan 8GB GDDR5 PCIe Video Card" "PowerColor Red Dragon Radeon RX 580 Dual-Fan 8GB GDDR5 PCIe Video Card"
[3] "ASUS PRIME Z270-AR LGA 1151 ATX Intel Motherboard"
[[73]][[5]]
[1] "$329.99" "$329.99" "$159.99"
[[73]][[6]]
[1] "1" "1" "1"
[[73]][[7]]
[1] "Visa"
[[74]]
[[74]][[1]]
[1] 74
[[74]][[2]]
[1] "Order #: 065-PO-4079152"
[[74]][[3]]
[1] "Saturday, September 16 2017"
[[74]][[4]]
[1] "Olympia Tools Tool Set 53 Piece" "The Best Connection Cable Ties"
[[74]][[5]]
[1] "$12.99" "$1.99"
[[74]][[6]]
[1] "1" "1"
[[74]][[7]]
[1] "Visa"
这里有一个dput()
list(list(1, "Order #: 065-PO-4166764", "Friday, December 22 2017",
c("Belkin 12 Outlet Home Theater Surge Protector 3996 Joules with Phone/Fax/Coax Protection & 8 ft. Cord - Black",
"Match Competitor"), c("$25.90", "$0.00"), c("5", "1"), "Visa"),
list(2, "Order #: 065-PO-4067551", "Saturday, September 2 2017",
c("MSI Gaming X Radeon RX-580 Dual-Fan 8GB GDDR5 PCIe Video Card",
"QVS HDMI Female to DVI-D Male Video Adapter - Black",
"MSI Radeon RX 580 GAMING X 4GB GDDR5 Video Card"), c("$329.99",
"$9.99", "$269.99"), c("1", "1", "1"), "Master Card"),
list(3, "Order #: 041-PO-8823995", "Sunday, August 27 2017",
"MSI Armor Radeon RX-470 Overclocked Dual-Fan 8GB GDDR5 PCIe Video Card",
"$279.99", "1", "Master Card"))
更新
该帖子已被版主标记为其他帖子的副本(例如,和),但事实并非如此。还有其他文章描述了如何将数据帧列表折叠成单个数据帧,但这不是我的内容。我有一个需要整理的列表。现在,肯定有一些帖子描述了列表的折叠列表,但我发现没有一篇帖子描述了子列表中的项目之间存在一对多关系的情况,其中需要回收。例如,在第一个示例文章中,每个子列表只包含一个元素,而我正在处理的列表有几个长度不等的元素,我的较短向量需要在每个列表中循环使用。第二个示例帖子也没有提到我的情况,因为在这种情况下,OP有一个数据帧列表。如果我有一个数据帧列表,我的问题将通过一个低效的do.call语句得到解决。重申一下,我的问题是,我有一个长度不均匀的列表列表,每个子列表(不在数据帧中)必须在较长的元素中循环使用较短的元素,以高效地形成数据帧。我希望这能澄清问题。因此,我想我通过结合stackoverflow和“互联网络”上其他地方的一些解决方案,找到了一些可能的答案。事实上,我将以下四个解决方案拼凑在一起:
docall_DF<-do.call("rbind", lapply(ProductList, data.frame))
library(data.table)
rbindlist_DF<-as.data.frame(data.table::rbindlist(lapply(ProductList, data.frame)))
library(plyr)
plyr_rbind_DF<-plyr::rbind.fill(lapply(ProductList, data.frame))
plyr_ldply_DF = plyr::ldply(lapply(ProductList, data.frame), data.frame)
话虽如此,我还是把这篇文章留了一会儿,希望其他人能提供一些额外的/更好的答案。你可以做以下几点:
do.call(rbind.data.frame,lapply(lst,function(x)as.matrix(unname(do.call(data.frame,rbind(x))))))
V1 V2 V3
1 1 Order #: 065-PO-4166764 Friday, December 22 2017
2 1 Order #: 065-PO-4166764 Friday, December 22 2017
3 2 Order #: 065-PO-4067551 Saturday, September 2 2017
4 2 Order #: 065-PO-4067551 Saturday, September 2 2017
5 2 Order #: 065-PO-4067551 Saturday, September 2 2017
6 3 Order #: 041-PO-8823995 Sunday, August 27 2017
V4 V5 V6
1 Belkin 12 Outlet Home Theater Surge Protector 3996 Joules with Phone/Fax/Coax Protection & 8 ft. Cord - Black $25.90 5
2 Match Competitor $0.00 1
3 MSI Gaming X Radeon RX-580 Dual-Fan 8GB GDDR5 PCIe Video Card $329.99 1
4 QVS HDMI Female to DVI-D Male Video Adapter - Black $9.99 1
5 MSI Radeon RX 580 GAMING X 4GB GDDR5 Video Card $269.99 1
6 MSI Armor Radeon RX-470 Overclocked Dual-Fan 8GB GDDR5 PCIe Video Card $279.99 1
V7
1 Visa
2 Visa
3 Master Card
4 Master Card
5 Master Card
6 Master Card
请使用dput
提供示例数据。@在服务器上,我已经更新了帖子,使示例列表的ASCII表示形式可供下载。谢谢你的建议。你应该在你的文章中以可复制和可复制粘贴的格式包含样本数据。许多用户不愿意通过文件宿主(包括我自己)下载文件。您的列表的ASCII表示形式没有用处,因为我们无法复制和粘贴。因此,请编辑您的帖子,并将dput
输出直接包含在您的帖子中。@sever,很好。我也总是害怕相信下载链接。我已经用dput输出更新了我的帖子。您提供的帖子不是重复的,因为它显示了一个数据帧列表。我的列表是一个列表,其中包含大小不等的元素,这些元素必须在较长的元素中循环使用。好的,感谢您澄清并使您的示例重现。
test replications elapsed relative
2 rbindlist_DF <- as.data.frame(data.table::rbindlist(lapply(ProductList, data.frame))) 100 9.03 1.000
1 docall_DF <- do.call("rbind", lapply(ProductList, data.frame)) 100 10.44 1.156
3 plyr_rbind_DF <- plyr::rbind.fill(lapply(ProductList, data.frame)) 100 10.44 1.156
4 plyr_ldply_DF 100 11.70 1.296
do.call(rbind.data.frame,lapply(lst,function(x)as.matrix(unname(do.call(data.frame,rbind(x))))))
V1 V2 V3
1 1 Order #: 065-PO-4166764 Friday, December 22 2017
2 1 Order #: 065-PO-4166764 Friday, December 22 2017
3 2 Order #: 065-PO-4067551 Saturday, September 2 2017
4 2 Order #: 065-PO-4067551 Saturday, September 2 2017
5 2 Order #: 065-PO-4067551 Saturday, September 2 2017
6 3 Order #: 041-PO-8823995 Sunday, August 27 2017
V4 V5 V6
1 Belkin 12 Outlet Home Theater Surge Protector 3996 Joules with Phone/Fax/Coax Protection & 8 ft. Cord - Black $25.90 5
2 Match Competitor $0.00 1
3 MSI Gaming X Radeon RX-580 Dual-Fan 8GB GDDR5 PCIe Video Card $329.99 1
4 QVS HDMI Female to DVI-D Male Video Adapter - Black $9.99 1
5 MSI Radeon RX 580 GAMING X 4GB GDDR5 Video Card $269.99 1
6 MSI Armor Radeon RX-470 Overclocked Dual-Fan 8GB GDDR5 PCIe Video Card $279.99 1
V7
1 Visa
2 Visa
3 Master Card
4 Master Card
5 Master Card
6 Master Card