我有一个包含100000行数据的数据集。我试图在Excel中做一些countif
操作,但它的速度非常慢。所以我想知道这种操作是否可以在R中完成?基本上,我想根据多种条件进行计数。例如,我可以依靠职业和性别
row sex occupation
1 M Student
2 F Analyst
2 M Analyst
十分简单。您的数据框将如下所示:
df <- data.frame(sex=c('M','F','M'),
occupation=c('Student','Analyst','Analyst'))
然后,您可以通过首先指定COUNTIF
部分来执行相当于IF
的操作,如下所示:
df$sex == 'M'
这将给你一个布尔矢量,即TRUE
和FALSE
的矢量。你想要的是计算条件为TRUE
的观察结果。因为在R TRUE
和FALSE
加倍为1和0,你可以简单地在布尔向量上sum()
。因此,相当于COUNTIF(sex='M')
sum(df$sex == 'M')
如果没有指定sex
的行,上面将返回NA
。在这种情况下,如果你只是想忽略缺失的观察结果
sum(df$sex == 'M', na.rm=TRUE)
这里有一个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
表是显而易见的选择,但它返回类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
给定一个数据集
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',])