首页 > 解决方案 > 使用回收的向量元素将 R 列表转换为数据框

问题描述

自从我在 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放置列表的 ASCII 表示,使用建议用户和我也将原始输出放在这篇文章的末尾)。我尝试在 stackoverflow 上搜索帖子,但似乎没有一个真正解决这个问题。谢谢你的帮助。dput()dput()

列表片段

[[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 语句来解决。重申一下,我的问题是我有一个长度不均匀的列表和每个子列表(不在数据框中),必须与较长元素之间的每个循环中的较短元素进行折叠,以有效地形成数据框。我希望这可以澄清。

标签: rlistdataframemultidimensional-arraylapply

解决方案


您可以执行以下操作:

 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

推荐阅读