【问题标题】:how to realize countifs function (excel) in R如何在R中实现countifs函数(excel)
【发布时间】:2014-04-10 23:05:58
【问题描述】:

我有一个包含 100000 行数据的数据集。我尝试在 Excel 中进行一些countif 操作,但速度非常慢。所以我想知道这种操作是否可以在R中完成?基本上,我想根据多个条件进行计数。例如,我可以指望职业和性别

row sex occupation
  1   M    Student
  2   F    Analyst
  2   M    Analyst

【问题讨论】:

  • 您需要的输出是什么? tableaggregate 或类似的功能可能是您想要的。
  • 您可以在 Excel 中使用数据透视。

标签: r


【解决方案1】:

简单易懂。您的数据框将如下所示:

df <- data.frame(sex=c('M','F','M'),
                 occupation=c('Student','Analyst','Analyst'))

然后您可以通过首先指定 IF 部分来执行 COUNTIF 的等效操作,如下所示:

df$sex == 'M'

这将为您提供一个布尔向量,即TRUEFALSE 的向量。您想要的是计算条件为TRUE 的观察值。由于在 R 中 TRUEFALSE 加倍为 1 和 0,您可以简单地将 sum() 覆盖在布尔向量上。因此,COUNTIF(sex='M') 的等价物是

sum(df$sex == 'M')

如果存在未指定sex 的行,上述将返回NA。在这种情况下,如果您只想忽略缺失的观察结果,请使用

sum(df$sex == 'M', na.rm=TRUE)

【讨论】:

    【解决方案2】:

    这里是一个有 100000 行的例子(这里从 A 到 Z 设置职业):

    > a = data.frame(sex=sample(c("M", "F"), 100000, replace=T), occupation=sample(LETTERS, 100000, replace=T))
    > sum(a$sex == "M" & a$occupation=="A")
    [1] 1882
    

    返回职业为“A”的男性人数。

    编辑

    我从您的评论中了解到,您想要计算所有可能的性别和职业组合。 所以首先创建一个包含所有组合的数据框:

    combns = expand.grid(c("M", "F"), LETTERS)
    

    并使用apply 循环以求和您的标准并将结果附加到combns

    combns = cbind (combns, apply(combns, 1, function(x)sum(a$sex==x[1] & a$occupation==x[2])))
    colnames(combns) = c("sex", "occupation", "count")
    

    结果的第一行如下所示:

      sex occupation count
    1   M          A  1882
    2   F          A  1869
    3   M          B  1866
    4   F          B  1904
    5   M          C  1979
    6   F          C  1910
    

    这能解决您的问题吗?

    或:

    thelatemai 建议的更简单的解决方案:

    table(a$sex, a$occupation)
    
    
           A    B    C    D    E    F    G    H    I    J    K    L    M    N    O
      F 1869 1904 1910 1907 1894 1940 1964 1907 1918 1892 1962 1933 1886 1960 1972
      M 1882 1866 1979 1904 1895 1845 1946 1905 1999 1994 1933 1950 1876 1856 1911
    
           P    Q    R    S    T    U    V    W    X    Y    Z
      F 1908 1907 1883 1888 1943 1922 2016 1962 1885 1898 1889
      M 1928 1938 1916 1927 1972 1965 1946 1903 1965 1974 1906
    

    【讨论】:

      【解决方案3】:

      给定一个数据集

      df <- data.frame( sex = c('M', 'M', 'F', 'F', 'M'), 
                        occupation = c('analyst', 'dentist', 'dentist', 'analyst', 'cook') )
      

      您可以对行进行子集化

      df[df$sex == 'M',] # To get all males
      df[df$occupation == 'analyst',] # All analysts
      

      等等

      如果要获取行数,只需调用函数nrow

      nrow(df[df$sex == 'M',])
      

      【讨论】:

        【解决方案4】:

        Table 是显而易见的选择,但它返回一个 table 类的对象,这需要一些烦人的步骤才能转换回 data.frame 所以,如果你可以使用 dplyr,你可以使用命令tally:

            library(dplyr)
            df = data.frame(sex=sample(c("M", "F"), 100000, replace=T), occupation=sample(c('Analyst', 'Student'), 100000, replace=T)
            df %>% group_by_all() %>% tally()
        
        
        # A tibble: 4 x 3
        # Groups:   sex [2]
          sex   occupation `n()`
          <fct> <fct>      <int>
        1 F     Analyst    25105
        2 F     Student    24933
        3 M     Analyst    24769
        4 M     Student    25193
        

        【讨论】:

          【解决方案5】:
          library(matrixStats)
          > data <- rbind(c("M", "F", "M"), c("Student", "Analyst", "Analyst"))
          > rowCounts(data, value = 'M') # output = 2 0
          > rowCounts(data, value = 'F') # output = 1 0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-17
            • 1970-01-01
            • 2021-11-07
            • 2021-11-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多