在R中对多个变量进行分组

4
我是一个熟练使用Excel数据透视表的用户,现在正在努力学习R语言。我知道如何在Excel中进行这种分析,但无法找到在R中编写代码的正确方法。
我试图通过2个不同的变量对用户数据进行分组,并将这些变量分组为范围(或bin),然后汇总其他变量。
以下是数据样本:
userid  visits  posts   revenue
1       25      0       25
2       2       2       0
3       86      7       8
4       128     24      94
5       30      5       18
…       …       …        …
280000  80      10      100
280001  42      4       25
280002  31      8       17

这是我想要输出的结果:
VisitRange  PostRange   # of Users  Total Revenue   Average Revenue
0           0           X            Y              Z
1-10        0           X   Y   Z
11-20       0           X   Y   Z
21-30       0           X   Y   Z
31-40       0           X   Y   Z
41-50       0           X   Y   Z
> 50        0           X   Y   Z
0           1-10        X            Y              Z
1-10        1-10        X            Y              Z
11-20       1-10        X            Y              Z
21-30       1-10        X            Y              Z
31-40       1-10        X            Y              Z
41-50       1-10        X            Y              Z
> 50        1-10        X            Y              Z

想要按访问量和帖子数量分组,每组10个,直到达到某个级别,然后把大于50的一组为“> 51”。
我已经尝试使用tapply和ddply来实现这个需求,但我认为它们不会按照我的期望工作,但我可能是错的。
最后,我知道我可以使用SQL,在if/then语句中识别访问量和帖子数量的范围(例如-如果访问量在1到10之间,则为“1-10”),然后仅按访问量范围和帖子范围进行分组,但我的目标是开始强迫自己使用R。也许R在这里不是正确的工具,但我认为它是...
非常感谢您提供的任何帮助。预先致谢。

欢迎来到SO。希望您很快能够戒掉对Excel的痴迷。(这对我有用!现在我只在被迫的情况下使用Excel...) - Andrie
谢谢。我因多年使用而非常熟悉Excel,但我也读到过R在分析方面会更胜一筹。这是真的吗? - mikebmassey
1个回答

6
plyr包中的成语,特别是ddply,与Excel中的数据透视表非常相似。
在您的示例中,您需要做的唯一一件事是将您的分组变量cut成所需的断点,然后再传递给ddply。以下是一个示例:
首先,创建一些示例数据:
set.seed(1)
dat <- data.frame(
  userid = 1:500,
  visits =sample(0:50, 500, replace=TRUE),
  posts = sample(0:50, 500, replace=TRUE),
  revenue = sample(1:100, replace=TRUE)
  )

现在,使用 “cut” 将您的分组变量划分为所需的范围:
dat$PostRange <- cut(dat$posts, breaks=seq(0, 50, 10), include.lowest=TRUE)
dat$VisitRange <- cut(dat$visits, breaks=seq(0, 50, 10), include.lowest=TRUE)

最后,使用ddplysummarise:
library(plyr)
ddply(dat, .(VisitRange, PostRange), 
      summarise, 
      Users=length(userid), 
      `Total Revenue`=sum(revenue), 
      `Average Revenue`=mean(revenue))

结果如下:
   VisitRange PostRange Users Total Revenue Average Revenue
1      [0,10]    [0,10]    23          1318        57.30435
2      [0,10]   (10,20]    23          1136        49.39130
3      [0,10]   (20,30]    28          1499        53.53571
4      [0,10]   (30,40]    20           923        46.15000
5      [0,10]   (40,50]    14           826        59.00000
6     (10,20]    [0,10]    23          1227        53.34783
7     (10,20]   (10,20]    17           642        37.76471
8     (10,20]   (20,30]    20           888        44.40000
9     (10,20]   (30,40]    15           622        41.46667
10    (10,20]   (40,50]    21           968        46.09524
11    (20,30]    [0,10]    23          1226        53.30435
12    (20,30]   (10,20]    19          1021        53.73684
13    (20,30]   (20,30]    23          1380        60.00000
14    (20,30]   (30,40]     8           313        39.12500
15    (20,30]   (40,50]    19           710        37.36842
16    (30,40]    [0,10]    18           782        43.44444
17    (30,40]   (10,20]    25          1308        52.32000
18    (30,40]   (20,30]    14           553        39.50000
19    (30,40]   (30,40]    26          1131        43.50000
20    (30,40]   (40,50]    20          1295        64.75000
21    (40,50]    [0,10]    20           958        47.90000
22    (40,50]   (10,20]    21          1168        55.61905
23    (40,50]   (20,30]    20          1118        55.90000
24    (40,50]   (30,40]    20          1009        50.45000
25    (40,50]   (40,50]    20           934        46.70000

这非常有帮助。感谢您的答案和示例。我遇到困难的地方是当运行“dat$PostRange <- cut(dat$posts, breaks=seq(0, 50, 10), include.lowest=TRUE)”时,我想要“break”的变量至少有6位数字加2位小数(999999.00)。当我运行该函数时,它将数据“cut”成科学计数法,即使我关闭了科学计数法选项。有没有一种方法可以强制将其转换为整数/实数?再次感谢。 - mikebmassey
@mikebmassey 你可以使用 cut 有两种方式:一种是指定切割次数,另一种是指定切割点(可以是整数)。你还可以指定文本标签来描述间隔。最后,请记住科学计数法只是数字的一种表示方式。你总是可以使用 format 来美观地打印数字。 - Andrie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接