2014-04-10 15 views
6

Ho un set di dati contenente 100000 righe di dati. Ho provato a fare alcune operazioni su countif in Excel, ma era proibitivamente lento. Quindi mi chiedo se questo tipo di operazione può essere fatto in R? Fondamentalmente, voglio fare un conteggio basato su più condizioni. Per esempio, posso contare sia per l'occupazione che per il sessocome realizzare la funzione di countifs (excel) in R

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

Qual 'è la richiesta di uscita? 'table' o' aggregate' o una funzione simile è probabilmente quello che vuoi. – thelatemail

+0

potresti usare un pivot in Excel. – flodel

risposta

11

Easy peasy. La cornice di dati sarà simile a questa:

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

Si può quindi fare l'equivalente di un COUNTIF specificando prima la parte IF, in questo modo:

df$sex == 'M' 

questo vi darà un vettore booleano, vale a dire un vettore di TRUE e FALSE. Quello che vuoi è contare le osservazioni per le quali la condizione è TRUE. Poiché in R TRUE e FALSE doppio come 1 e 0 è possibile semplicemente sum() sul vettore booleano. L'equivalente di COUNTIF(sex='M') è quindi

sum(df$sex == 'M') 

Dovrebbe esserci righe in cui il sex non specificato sopra restituirà NA. In tal caso, se si desidera solo per ignorare le osservazioni mancanti utilizzano

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

Dato un insieme di dati

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

si può sottoinsieme righe

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

ecc

Se vuoi ottenere il numero di righe, basta chiamare la funzione nrow come

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

Ecco un esempio con 100000 righe (occupazioni sono impostati qui dalla A alla 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 

restituisce il numero di maschi con occupazione "A".

EDIT

quanto ho capito dal tuo commento, si desidera che i conti di tutte le possibili combinazioni di sesso e occupazione. Quindi, prima di creare un dataframe con tutte le combinazioni:

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

e ciclo con apply per riassumere per i criteri e aggiungere i risultati alla combns:

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

Le prime righe del tuo look risultato come segue:

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 

Questo risolve il problema?

O:

soluzione Molto più facile suggerito da 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