如何在R中实现countifs功能(excel)

时间:2014-04-10 23:05:59

标签: r

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

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

5 个答案:

答案 0 :(得分:13)

容易腻。您的数据框将如下所示:

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

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

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)

答案 1 :(得分:4)

这里有一个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

返回有职业的男性人数&#34; A&#34;。

修改

正如我从你的评论中所理解的那样,你想要所有可能的性别和职业组合的数量。 因此,首先要创建一个包含所有组合的数据框:

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

答案 2 :(得分:1)

表是显而易见的选择,但是它返回类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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

给定数据集

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',])