【问题标题】:Classify or cut dataframe by list of class range and summarize it with ddply通过类范围列表对数据帧进行分类或剪切,并用 ddply 进行汇总
【发布时间】:2011-04-22 11:13:24
【问题描述】:

我对 ddply 和子集有疑问。

我有这样的数据框 df:

df <- read.table(textConnection(
"   id v_idn v_seed v_time v_pop v_rank v_perco 
    1  15    125648 0      150   1      15      
    2  17    125648 0      120   2      5       
    3  18    125648 0      100   3      6       
    4  52    125648 0      25    4      1       

    5  17    125648 10     220   1      5      
    6  15    125648 10     160   2      15       
    7  18    125648 10     110   3      6      
    8  52    125648 10     50    4      1       

    9  56   -11152  0      250   1      17      
    10 15   -11152  0      180   2      15      
    11 18   -11152  0      110   3      6       
    12 22   -11152  0      5     4      14      

    13 56   -11152  10     250   1      17      
    14 15   -11152  10     180   2      15      
    15 22   -11152  10     125   3      14      
    16 18   -11152  10     120   4      6 "), header=TRUE)      

第一步:

我有一个与 cut_interval 等间隔的列表,如下所示:

myinterval <- cut_interval(c(15,5,6,1,17,14), length=10)  

所以我这里有两个级别:[0,10) 和 (10,20]

第二步:

我希望每个组/类都由我在 v_cut 中的两个级别定义......就像这样:

id v_idn v_seed v_time v_pop v_rank v_perco v_cut
1  15    125648 0      150   1      15      (10,20]
2  17    125648 0      120   2      5       [0,10)
3  18    125648 0      100   3      6       [0,10)
4  52    125648 0      25    4      1       [0,10)

5  17    125648 10     220   1      5       [0,10)
6  15    125648 10     160   2      15      (10,20] 
7  18    125648 10     110   3      6       [0,10)
8  52    125648 10     50    4      1       [0,10)

9  56   -11152  0      250   1      17      (10,20]
10 15   -11152  0      180   2      15      (10,20]
11 18   -11152  0      110   3      6       [0,10)
12 22   -11152  0      5     4      14      (10,20]

13 56   -11152  10     250   1      17      (10,20]
14 15   -11152  10     180   2      15      (10,20]
15 22   -11152  10     125   3      14      (10,20]
16 18   -11152  10     120   4      6       [0,10)

第 3 步:

我想知道每个组 v_cut 的 x 轴的 v_rank 和 y 轴的时间的可变性,所以我需要用类似的东西计算 v_rank 值的 min、mean、max、sd

ddply(df, .(v_cut,v_time), summarize ,mean = mean(v_rank), min = min(v_rank), max = max(v_rank), sd = sd(v_rank))

*需要的结果:*

id  v_time MEAN.v_rank ... v_cut
1   0      2.25            (10,20]
2   0      2.42            [0,10)
3   10     2.25            [0,10)
4   10     2.42            (10,20]

我的问题

我不知道如何通过第 1 步 -> 第 2 步:/

如果可以像我在步骤 3 中的示例那样按 v_cut 分组?

是否有可能用 ddply 的“子集”选项做同样的事情?

再一次,非常感谢您的帮助伟大的R大师!

更新 1:

我有一个答案可以从第 1 步到第 2 步:

df$v_cut <- cut_interval(df$v_perco,n=10)

我正在使用 plyr,但在这种情况下可能有更好的答案?

回答到第2步到第3步?

更新 2:

Brandon Bertelsen 用 melt + cast 给了我一个很好的答案,但现在(要理解)我想用 plyr 和 ddply 进行相同的操作 .. 得到不同的结果:

id  v_idn v_time MEAN.v_rank ... v_cut
    1   15   0      2.25            (10,20]
    2   15   10     2.45            (10,20]
    2   17   0      1.52            [0,10)
    2   17   10     2.42            [0,10)
    etc. 

我正在尝试这样的事情:

r('sumData <- ddply(df, .(v_idn,v_time), summarize,min = min(v_rank),mean =  mean(v_rank), max = max(v_rank), sd=sd(v_rank))')

但是我想在我的 sumData 数据框中有 v_cut,我该如何处理 ddply ?有没有办法做到这一点?或者与初始 df 和 key = v_idn 合并以将列 v_cut 添加到 sumData 是唯一好的答案?

【问题讨论】:

  • 一些来自 dput(head(df),5) 的测试数据会有所帮助。
  • 对于更新 2:我不确定您如何计算 2.25。因为在您的示例表中:v_idn = 15 & v_time = 0,我们有 v_rank n=2, sum=3 (1+2) 因此平均值为 sum/n = 1.5。

标签: r subset summary cut plyr


【解决方案1】:

你真的不需要 plyr,你可以使用reshape

## Pull what you need
dfx <- df[c("v_seed", "v_time","v_rank","v_perco")]
## Bring in your cuts
dfx <- data.frame(dfx, ifelse(df$v_perco > 10,"(10,20]", "[0,10)")))
## Rename v_cut
colnames(dfx)[ncol(dfx)] <- "v_cut"       
## Melt it.    
dfx <- melt(dfx, id=c("v_cut", "v_seed", "v_time"))
## Cast it.
dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, c(mean,min,max,sd))

如果你只想要平均值,那么将最后一行替换为:

dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, mean)

键入“dfx”,您将看到一个包含您要求的数据框。

【讨论】:

  • 感谢您的帮助,我正在尝试您的解决方案,但我对“cast”行有一些问题,df 数据框中不存在“bound”。你有这个函数的一些好的文档,因为 ?cast 或 ?melt 看起来很神秘:s
  • 哎呀,“绑定”应该是 v_cut
  • 我不确定你想从 v_cut 得到什么,提供的削减不会将其分成 10 个箱子,而是 n=10,表示 10 个箱子。我想你想要的是 cut_interval(x, length=10)。
  • 哼,你的ifelse函数好像有问题。对于 v_perco > 10 和反向,我在 v_cut 列中有 [0,10] 值。
  • 是的,它的工作!我用其他问题和其他类型的结果更新原始帖子...
【解决方案2】:

你只是语法有问题:

## Add your cut
df.new <- data.frame(df, ifelse(df$v_perco > 10,"(10,20]", "[0,10)"))
## Rename v_cut
colnames(df.new)[ncol(df.new)] <- "v_cut"   

## Careful here read the note below
df.new <- ddply(df.new, .(v_idn, v_time), function(x) unique(data.frame(
mean =  mean(x$v_rank),
v_cut = x$v_cut
)))

或者:

ddply(df.new, .(v_idn, v_time), summarise, mean=mean(v_rank))

使用 ".(v_idn, v_time)" 你告诉 ddply 对于 v_idn 和 v_time 的每个组合,你希望它计算 v_rank 的平均值。

【讨论】:

    猜你喜欢
    • 2013-02-13
    • 2013-07-16
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2014-07-04
    相关资源
    最近更新 更多