【问题标题】:Looking for a better way of creating a new data.frame with purchase frequency information from another data.frame寻找一种更好的方法来创建一个新的 data.frame,其中包含来自另一个 data.frame 的购买频率信息
【发布时间】:2014-03-24 18:00:33
【问题描述】:

好的,这可能有点令人费解,但我会尝试解释我的意思:

我有一个 data.frame,它告诉我几年中每天在不同时段销售的不同类别的产品数量,并为每个类别中的每个产品提供一个 True/False 列,告诉我是否在该会话中至少售出了一种此类产品。

这是一个小例子:

    Year    Month   Day Session  Number Sold  At Least One of X
    2014    1        15 19876         10         True
    2014    1        15 25698         10         False
    2014    1        15 2156           2         True
    2014    1        16 21578          0         False
    2014    1        16 1123          12         False
    2014    1        16 15469         25         True
    2014    1        16 32654          0         False
    2014    1        17 12589          8         True
    2014    1        18 54269          4         True
    2014    1        18 25136         14         True

所以,第一次观察,该类别有 10 件商品已售出,其中至少有一件是产品 X。在下一个会话中,该类别中售出 10 件,但都不是产品 X。

这是上表的 dput():

structure(list(year = c(2014, 2014, 2014, 2014, 2014, 2014, 2014, 
2014, 2014, 2014), month = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), day = c(15, 
15, 15, 16, 16, 16, 16, 17, 18, 18), session = c(19876, 25698, 
2156, 21578, 1123, 15469, 32654, 12589, 54269, 25136), numbsold = c(10, 
10, 2, 0, 12, 25, 0, 8, 4, 14), min1x = structure(c(2L, 1L, 2L, 
1L, 1L, 2L, 1L, 2L, 2L, 1L), .Label = c("False", "True"), class = "factor")), .Names = c("year", 
"month", "day", "session", "numbsold", "min1x"), row.names = c(NA, 
-10L), class = "data.frame")

因此,我正在制作 data.frames,以显示 X 在一年中的每一天至少是其类别中购买的产品之一的时间百分比。我希望得到以下输出:

      Date      Frequency Sold
    2014-01-15  0.6666667
    2014-01-16  0.5000000
    2014-01-17  1.0000000
    2014-01-18  0.5000000

由于我对 R 的了解极其有限(我正在学习,但速度很慢),我知道可以这样做:

  myout<-data.frame(c("1/15/2014","1/16/2014","1/17/2014","1/18/2014"),
              c(sum(mydf$min1x=="True" & mydf$year==2014 & mydf$month==1 & mydf$day==15)
                /sum(mydf$numbsold > 0 & mydf$year==2014 & mydf$month==1 & mydf$day == 15)
              ,sum(mydf$min1x=="True" & mydf$year==2014 & mydf$month==1 & mydf$day==16)
                 /sum(mydf$numbsold > 0 & mydf$year==2014 & mydf$month==1 & mydf$day == 16)
              ,sum(mydf$min1x=="True" & mydf$year==2014 & mydf$month==1 & mydf$day==17)
                 /sum(mydf$numbsold > 0 & mydf$year==2014 & mydf$month==1 & mydf$day == 17)
              ,sum(mydf$min1x=="True" & mydf$year==2014 & mydf$month==1 & mydf$day==18)
                 /sum(mydf$numbsold > 0 & mydf$year==2014 & mydf$month==1 & mydf$day == 18)))
names(myout)<-c("Date","Frequency Sold")
myout$Date<-as.Date(myout$Date, "%m/%d/%Y")  

我基本上是在重复命令并强制它一天一次地构建 data.frame。当然,在两年的时间和数十种不同的产品中这样做会很快。

我可以用什么来告诉 R 为特定产品构建一个 data.frame,显示该产品在数据集中找到的每个日期在其类别中至少完成一次购买的时间百分比?

谢谢!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    使用data.table 包(您必须安装它)可以很好地解决这个问题。

    首先从年、月、日列中创建一个日期列:

    mydf$Date = as.Date(paste(mydf$year, mydf$month, mydf$day, sep="-"))
    

    然后把它变成data.table

    library(data.table)
    mydt = as.data.table(mydf)
    

    然后您可以执行此汇总操作:

    mydt[, list(FrequencySold=mean(min1x[numbsold > 0] == "True")), by=Date]
    

    【讨论】:

    • data.table 绝对是一种方法,但是,您的汇总操作并没有提供他想要的输出。
    • @iShouldUseAName:是的,我花了一秒钟才意识到这一点(自修复以来)
    • @iShouldUseAName 和 OP-您的两个解决方案都运行良好。谢谢。它们只是做同一件事的两种方法吗(在 R 中似乎很常见)......即你们都认为使用一个比另一个有优势吗?
    • @iShouldUseAName 你不能认真看待你的解决方案和这个并声称你的解决方案更容易阅读/理解; @datahappy - data.table 通常会更快、更容易读/写
    • @iShouldUseAName 基本的data.table 表达式,就像在这个答案中一样,非常容易学习 - 你需要理解的是d[i, j, by = b] 被读作 take d, apply i, then计算每个组 b 的 j;更高级的会有.SD.N之类的东西,一旦你理解了上面的内容,就很容易掌握了。
    【解决方案2】:
    require(plyr)
    df$min1x <- as.logical(df$min1x)
    ddply(df[df$numbsold > 0, ], .(year, month, day), summarize, frequency=sum(min1x) / length(min1x) )
    

    其中df 是您提供的data.frame。您需要自己制定日期。

    【讨论】:

    • 实际上,这也没有提供所需的输出。看起来他想将其限制在 numbsold 不是 0 的情况下
    • 好电话。我现在就做出改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多