【问题标题】:Reframing magic on data.frame [duplicate]在data.frame上重构魔法[重复]
【发布时间】:2023-03-06 12:09:01
【问题描述】:

我目前正在学习使用 data.frame 并且对如何重新排序它们感到很困惑。

目前,我有一个 data.frame 显示:

  • 第 1 栏:商店名称
  • 第 2 栏:产品
  • 第3栏:本店购买该商品的次数

或者在视觉上是这样的:

+---+-----------+-------+----------+--+
|   | Shop.Name | Items | Product  |  |
+---+-----------+-------+----------+--+
| 1 | Shop1     |     2 | Product1 |  |
| 2 | Shop1     |     4 | Product2 |  |
| 3 | Shop2     |     3 | Product1 |  |
| 4 | Shop3     |     2 | Product1 |  |
| 5 | Shop3     |     1 | Product4 |  |
+---+-----------+-------+----------+--+

我想要实现的是以下“以商店为中心”的结构:

  • 第 1 栏:商店名称
  • 第 2 栏:为 product1 出售的商品
  • 第 3 栏:为 product2 出售的商品
  • 第 4 栏:为 product3 出售的商品 ...

当没有特定商店/产品的行时(因为没有销售),我想创建一个 0。

+---+-------+-------+-------+-------+-------+-----+--+--+
|   | Shop  | Prod1 | Prod2 | Prod3 | Prod4 | ... |  |  |
+---+-------+-------+-------+-------+-------+-----+--+--+
| 1 | Shop1 |     2 |     4 |     0 |     0 | ... |  |  |
| 2 | Shop2 |     3 |     0 |     0 |     0 | ... |  |  |
| 3 | Shop3 |     2 |     0 |     0 |     1 | ... |  |  |
+---+-------+-------+-------+-------+-------+-----+--+--+

【问题讨论】:

标签: r dataframe reshape


【解决方案1】:

使用reshape2 库中的dcast

library(reshape2)

> df <- data.frame(Shop.Name=rep(c("Shop1","Shop2","Shop3"),each=3),
+                  Items=rpois(9,5),
+                  Product=c(rep(c("Prod1","Prod2","Prod3","Prod4"),2),"Prod5")
+ )
> df
  Shop.Name Items Product
1     Shop1     6   Prod1
2     Shop1     5   Prod2
3     Shop1     6   Prod3
4     Shop2     5   Prod4
5     Shop2     6   Prod1
6     Shop2     6   Prod2
7     Shop3     4   Prod3
8     Shop3     7   Prod4
9     Shop3     5   Prod5
> dcast(df,Shop.Name ~ Product,value.var="Items",fill=0)
  Shop.Name Prod1 Prod2 Prod3 Prod4 Prod5
1     Shop1     6     5     6     0     0
2     Shop2     6     6     0     5     0
3     Shop3     0     0     4     7     5

【讨论】:

【解决方案2】:

如果你出于任何原因想使用原来的 reshape 包:

Shop.Name <- c("Shop1", "Shop1", "Shop2", "Shop3", "Shop3")
Items <- c(2,4,3,2,1)
Product <- c("Product1", "Product2", "Product1", "Product1", "Product4")
(df <- data.frame(Shop.Name, Items, Product))

cast(df, formula = Shop.Name ~ Product, value="Items", fill=0)

【讨论】:

    【解决方案3】:

    到目前为止,答案在一定程度上有效,但并未完全回答您的问题。特别是,它们没有解决没有商店销售特定产品的案例的问题。从您的示例输入和所需输出来看,没有商店出售“Product3”。事实上,“Product3”甚至没有出现在您的源代码data.frame 中。此外,它们没有解决每个商店 + 产品组合有多个行的可能情况。

    这是您的数据的修改版本以及目前的两种解决方案。我为“Shop1”和“Product1”的组合添加了另一行。请注意,我已将您的产品转换为 factor 变量,其中包括该变量可以采用的级别,即使实际上没有一个案例具有该级别。

    mydf <- data.frame(
      Shop.Name = c("Shop1", "Shop1", "Shop2", "Shop3", "Shop3", "Shop1"),
      Items = c(2, 4, 3, 2, 1, 2),
      Product = factor(
        c("Product1", "Product2", "Product1", "Product1", "Product4", "Product1"),
        levels = c("Product1", "Product2", "Product3", "Product4")))
    
    1. dcast 来自“reshape2”

      library(reshape2)
      dcast(mydf, formula = Shop.Name ~ Product, value="Items", fill=0)
      # Using Product as value column: use value.var to override.
      # Aggregation function missing: defaulting to length
      # Error in .fun(.value[i], ...) : 
      #   2 arguments passed to 'length' which requires 1
      

      什么?突然不行了。改为这样做:

      dcast(mydf, formula = Shop.Name ~ Product, 
            fill = 0, value.var = "Items", 
            fun.aggregate = sum, drop = FALSE)
      #   Shop.Name Product1 Product2 Product3 Product4
      # 1     Shop1        4        4        0        0
      # 2     Shop2        3        0        0        0
      # 3     Shop3        2        0        0        1
      
    2. 让我们成为老派。 cast 来自“重塑”

      library(reshape)
      cast(mydf, formula = Shop.Name ~ Product, value="Items", fill=0)
      # Aggregation requires fun.aggregate: length used as default
      #   Shop.Name Product1 Product2 Product4
      # 1     Shop1        2        1        0
      # 2     Shop2        1        0        0
      # 3     Shop3        1        0        1
      

      嗯。又不是你想要的……试试这个吧:

      cast(mydf, formula = Shop.Name ~ Product, 
           value = "Items", fill = 0, 
           add.missing = TRUE, fun.aggregate = sum)
      #   Shop.Name Product1 Product2 Product3 Product4
      # 1     Shop1        4        4        0        0
      # 2     Shop2        3        0        0        0
      # 3     Shop3        2        0        0        1
      
    3. 让我们回到基础。 xtabs 来自基础 R

      xtabs(Items ~ Shop.Name + Product, mydf)
      #          Product
      # Shop.Name Product1 Product2 Product3 Product4
      #     Shop1        4        4        0        0
      #     Shop2        3        0        0        0
      #     Shop3        2        0        0        1
      

      或者,如果您更喜欢data.frame(请注意,您的“Shop.Name”变量已转换为data.framerow.names):

      as.data.frame.matrix(xtabs(Items ~ Shop.Name + Product, mydf))
      #       Product1 Product2 Product3 Product4
      # Shop1        4        4        0        0
      # Shop2        3        0        0        0
      # Shop3        2        0        0        1
      

    【讨论】:

    • 这比stackoverflow.com/questions/9617348/…中发布的其他解决方案要全面一些
    • @Anando Mahto,我正在处理同样的问题如果你有时间回答我的问题,我会很高兴的。在我的数据集中 shopname 是唯一的用户 ID,例如,如果用户 ID = 5,我想将其视为第一行。我该怎么做?非常感谢提前
    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2018-11-30
    相关资源
    最近更新 更多