【问题标题】:Calculating the occurrences of numbers in the subsets of a data.frame计算 data.frame 子集中出现的数字
【发布时间】:2011-07-17 06:12:54
【问题描述】:

我在 R 中有一个类似于以下的数据框。实际上,我真正的 'df' 数据框比这里的要大得多,但我真的不想让任何人感到困惑,所以这就是我尝试尽可能简化事情的原因。

这是数据框。

id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3)   
a <-c(3,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3)
b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1,3,2,1,1,1,2,1,3,1,2,2,1,3,3,2,3,2)
c <-c(1,3,2,3,2,1,2,3,3,2,2,3,1,2,3,3,3,1,1,2,3,3,1,2,2,3,2,2,3,2)
d <-c(3,3,3,1,3,2,2,1,2,3,2,2,2,1,3,1,2,2,3,2,3,2,3,2,1,1,1,1,1,2)
e <-c(2,3,1,2,1,2,3,3,1,1,2,1,1,3,3,2,1,1,3,3,2,2,3,3,3,2,3,2,1,3)

df <-data.frame(id,a,b,c,d,e)
df

基本上我想做的是获取每列 (a,b,c,d,e) 和每个 id 组 (1,2,3) 的数字出现次数(对于后面的分组,请参阅我的列'id')。

因此,对于“a”列和 id 编号“1”(对于后者,请参见“id”列),代码将是这样的:

as.numeric(table(df[1:10,2]))

##The results are:
[1] 3 7

只是简单解释一下我的结果:在“a”列(并且仅关于那些在“id”列中具有数字“1”的记录)我们可以说数字“1”出现了 3 次,而数字“3”出现了7 次。

再次,只是为您展示另一个示例。对于“a”列和 id 编号“2”(对于后者的分组,请再次参见“id”列):

as.numeric(table(df[11:20,2]))

##After running the codes the results are: 
[1] 4 3 3

让我再解释一下:在“a”列中,仅关于那些在“id”列中具有数字“2”的观察值)我们可以说数字“1”出现了 4 次,数字“2”出现了 3次和数字“3”出现了 3 次。

所以这就是我想做的。计算每个自定义子集的数字出现次数(然后将这些值收集到数据框中)。我知道这不是一项艰巨的任务,但问题是我必须定期更改输入“df”数据框,因此总行数和列数都可能随着时间而变化……

到目前为止,我所做的是按列分隔“df”数据框,如下所示:

for (z in (2:ncol(df))) assign(paste("df",z,sep="."),df[,z])

所以 df.2 将引用 df$a,df.3 将等于 df$b,df.4 将等于 df$c 等等。但是我现在真的被卡住了,我不知道如何前进…

是否有适当的“自动”方法来解决这个问题?

【问题讨论】:

    标签: r subset


    【解决方案1】:

    怎么样-

    > library(reshape)
    
    > dftab <- table(melt(df,'id'))
    > dftab
    , , value = 1
    
       variable
    id  a b c d e
      1 3 8 2 2 4
      2 4 6 3 2 4
      3 4 2 1 5 1
    
    , , value = 2
    
       variable
    id  a b c d e
      1 0 1 4 3 3
      2 3 3 3 6 2
      3 1 4 5 3 4
    
    , , value = 3
    
       variable
    id  a b c d e
      1 7 1 4 5 3
      2 3 1 4 2 4
      3 5 4 4 2 5
    

    所以要获取列 'a' 和组 '1' 中的 '3' 的数量 你可以这样做

    > dftab[3,'a',1]
    [1] 4
    

    【讨论】:

      【解决方案2】:

      tapplyapply 的组合可以创建您想要的数据:

      tapply(df$id,df$id,function(x) apply(df[id==x,-1],2,table))
      

      但是,当一个分组中没有所有元素时,例如1a,结果将是该id 组的列表,而不是一个漂亮的表格(矩阵)。

      $`1`
      $`1`$a
      
      1 3 
      3 7 
      
      $`1`$b
      
      1 2 3 
      8 1 1 
      
      $`1`$c
      
      1 2 3 
      2 4 4 
      
      $`1`$d
      
      1 2 3 
      2 3 5 
      
      $`1`$e
      
      1 2 3 
      4 3 3 
      
      
      $`2`
        a b c d e
      1 4 6 3 2 4
      2 3 3 3 6 2
      3 3 1 4 2 4
      
      $`3`
        a b c d e
      1 4 2 1 5 1
      2 1 4 5 3 4
      3 5 4 4 2 5
      

      【讨论】:

      • 您可以使用一个因子来确保零计数通过:lapply(split(df[-1], df$id), apply, 2, function(x) table(factor(x, 1:3)))
      【解决方案3】:

      我相信有人会有比这更优雅的解决方案,但您可以将它与一个简单的函数和来自plyr 包的dlply 拼凑在一起。

      ColTables <- function(df) {
        counts <- list()
        for(a in names(df)[names(df) != "id"]) {
          counts[[a]] <- table(df[a])
        }
        return(counts)
      }
      
      results <- dlply(df, "id", ColTables)
      

      这会让你返回一个列表——列表的第一个“层”将是 id 变量;第二个 table 为该 id 变量的每一列结果。例如:

      > results[['2']]['a']
      $a
      
      1 2 3 
      4 3 3 
      

      对于 id 变量 = 2,column = a,根据您的上述示例。

      【讨论】:

        【解决方案4】:

        一种方法是使用aggregate 函数,但您必须在数据框中添加一列

        > df$freq <- 0
        > aggregate(freq~a+id,df,length)
          a id freq
        1 1  1    3
        2 3  1    7
        3 1  2    4
        4 2  2    3
        5 3  2    3
        6 1  3    4
        7 2  3    1
        8 3  3    5
        

        当然你可以写一个函数来做,这样更容易经常做,而且你不必在你的实际数据框中添加一列

        > frequency <- function(df,groups) {
        +   relevant <- df[,groups]
        +   relevant$freq <- 0
        +   aggregate(freq~.,relevant,length)
        + }
        > frequency(df,c("b","id"))
          b id freq
        1 1  1    8
        2 2  1    1
        3 3  1    1
        4 1  2    6
        5 2  2    3
        6 3  2    1
        7 1  3    2
        8 2  3    4
        9 3  3    4
        

        【讨论】:

          【解决方案5】:

          您没有说您希望数据如何。 by 函数可能会为您提供您喜欢的输出。

          by(df, df$id, function(x) lapply(x[,-1], table))
          

          【讨论】:

            猜你喜欢
            • 2015-01-14
            • 2021-05-01
            • 1970-01-01
            • 2014-05-13
            • 1970-01-01
            • 1970-01-01
            • 2020-02-21
            • 2012-02-12
            相关资源
            最近更新 更多