如何根据列传递ddply中的值?

时间:2013-01-22 19:54:11

标签: r dataframe plyr

我希望能够通过列Category传递两组值GROUPED。有没有办法可以使用ddply包中的plyr来执行此操作?

我想做这样的事情:

ddply(idata.frame(data), .(Category), wilcox.test, data[Type=="PRE",], data[Type=="POST",])

wilcox.test是以下功能:

Description

Performs one- and two-sample Wilcoxon tests on vectors of data; the latter is also known as ‘Mann-Whitney’ test.

Usage

wilcox.test(x, ...)

Arguments

x   
numeric vector of data values. Non-finite (e.g. infinite or missing) values will be omitted.

y   
an optional numeric vector of data values: as with x non-finite values will be omitted.

.... rest of the arguments snipped ....

我有dput的以下输出:

structure(list(Category = c("A", "C", 
"B", "C", "D", "E", 
"C", "A", "F", "B", 
"E", "C", "C", "A", 
"C", "A", "B", "H", 
"I", "A"), Type = c("POST", "POST", 
"POST", "POST", "PRE", "POST", "POST", "PRE", "POST", 
"POST", "POST", "POST", "POST", "PRE", "PRE", "POST", 
"POST", "POST", "POST", "POST"), Value = c(1560638113, 
1283621, 561329742, 2727503, 938032, 4233577690, 0, 4209749646, 
111467236, 174667894, 1071501854, 720499, 2195611, 1117814707, 
1181525, 1493315101, 253416809, 327012982, 538595522, 3023339026
)), .Names = c("Category", "Type", "Value"), row.names = c(21406L, 
123351L, 59875L, 45186L, 126720L, 94153L, 48067L, 159371L, 54303L, 
63318L, 104100L, 58162L, 41945L, 159794L, 57757L, 178622L, 83812L, 
130655L, 30860L, 24513L), class = "data.frame")

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

我一直在做的是使用匿名函数:

ddply(idata.frame(data), .(Category), 
    function(x) wilcox.test(x[Type == "PRE",], x[Type == "POST",])

我不确定wilcox.test函数默认返回一个很好的连接到data.frame,所以你必须稍微调整一下自己。或者,使用dlply结束wilcox.test输出列表。

答案 1 :(得分:2)

这里有两个问题:

  1. 保罗的解决方案在我的案例中似乎不起作用,尽管我使用的是相同的数据。我认为子集化的语法是有原因的,但我没有设法破解错误。

  2. 根据您希望使用的结构(即Category x Type),您的数据实际上太小,无法通过统计测试进行比较。毕竟,如果你查看数据框中的类别数量,所有类别的值都少于30,而一半只有一个值:

    > table(data$Category)
    A B C D E F H I 
    5 3 6 1 2 1 1 1
    
  3. 但好消息是我找到了适合你的解决方案。

    首先,我必须生成一个更宽的表。而且因为我(非常)懒惰,我只是这样做了:

    for(i in 1:10){data <- rbind(data,data)}
    
    data$Value <- jitter(data$Value,5e3) 
    
    data$Type <- sample(c("POST","PRE"),size=nrow(data),replace=T,prob=c(0.80,0.20))
    

    我将表复制了10次,将噪声添加到数值中并随机地重新分配“PRE”和“POST”,其比例与初始数据框中添加的相同。请注意,值本身并不重要,我只是使用您提供给我们的相同数据结构。

    这样,我们最终得到了一个更大的表,更重要的是 - 更密集的表:

        > table(data$Category, data$Type)
    
          POST  PRE
        A 4135  985
        B 2470  602
        C 4881 1263
        D  814  210
        E 1634  414
        F  815  209
        H  846  178
        I  813  211
    

    这样就完成了!

    现在我们可以找到解决方案。为了清楚起见,我编写了分别执行Wilcoxon测试的函数。诀窍在于它必须返回一个向量,该向量将包含在输出所需的数据框中。

    让我们调用函数wx

     wx <- function(d){
     w <- wilcox.test(
      # First vector (x)
        subset(d, Type == "PRE", select = Value )[,1], 
        subset(d, Type == "POST", select = Value )[,1]
          )
      # c(1,3) returns the Stat and the P-value (tweak that if you want something else)
      return(w[c(1,3)])
      }
    

    最后,您只需将该功能应用于数据框:

    > ddply(data, .(Category), .fun = wx  )
        Category      V1        V2
               A 2047794 0.7862484
               B  725554 0.3585648
               C 3071435 0.8459535
               D   80693 0.2112926 
               E  347314 0.3984288
               F   83304 0.6252554
               H   71762 0.3247840
               I   88874 0.4177269
    

    当然,根据我构建表的方式,没有什么是重要的,但是你有V1的统计数据和V2的P值。