Подсчет вхождений в кадре данных с двумя условиями без цикла for

В настоящее время я использую набор данных «алмазы» из пакета ggplot2. Я хочу иметь возможность подсчитать количество бриллиантов, которые соответствуют двум условиям в первых n наблюдениях, в данном случае цвет «E» и чистота «SI2». Я написал функцию ниже, которая решает эту проблему, однако я хотел бы иметь возможность сделать это без необходимости запуска цикла for. Есть ли способ заставить эту функцию работать без цикла for? Набор данных содержит 54000 наблюдений.

library('ggplot2')
data(diamonds)

countfreq <- function(n) {
  #Set k to 0
  k <- 0
  for(i in 1:n) {
    if (diamonds$color[i] == 'E' & diamonds$clarity[i] == 'SI2') 
      k <- k + 1
  }
  return(k)
}

countfreq(50)
2
countfreq(100) 
3

Первые две строки кадра данных приведены ниже.

 carat  cut  color clarity  depth  table  price   x    y    z 
1 0.23 Ideal   E     SI2     61.5   55.0   326  3.95 3.98  2.43
2 0.21 Premium E     SI1     59.8   61.0   326  3.89 3.84  2.31 

person Macter    schedule 14.10.2017    source источник
comment
Пожалуйста, отметьте домашнюю работу как таковую в следующий раз (сразу после освежения индексации фрейма данных, векторизации и векторизованных логических операций). nrow(diamonds[diamonds$color == 'E' & diamonds$clarity == 'SI2',])   -  person hrbrmstr    schedule 14.10.2017
comment
Извините, я отредактировал выше, чтобы уточнить, что я хотел бы сохранить функцию (чтобы я мог легко изменять n без определения новых кадров данных каждый раз), но потерял цикл for.   -  person Macter    schedule 14.10.2017
comment
Вы действительно должны серьезно отнестись к освежению индексации фрейма данных, векторизации и векторизованных логических операций. Принятый вами аккуратный ответ является излишним, медленным и ненужным.   -  person hrbrmstr    schedule 15.10.2017


Ответы (1)


Я собираюсь дать вам кое-что, что ответит на ваш вопрос, а также поможет вам понять более общий подход к ответам на подобные вопросы с использованием пакета dplyr.

library(ggplot2)
library(dplyr)

diamonds %>% # take the diamonds data.fram and group it
    group_by(color, clarity) %>% # 56 groups
    summarize(count = n()) %>% # add a count column
    filter(color=="E", clarity=="SI2") %>%  # filter the row you want
    .$count # just the single value as a result

[1] 1713

Обратите внимание, что можно запустить любую часть кода, чтобы увидеть промежуточные результаты. Например, чтобы увидеть таблицу групп и количество для каждой, запустите только эту часть:

diamonds %>% # take the diamonds data.fram and group it
        group_by(color, clarity) %>% # 56 groups
        summarize(count = n())

# A tibble: 56 x 3
# Groups:   color [?]
   color clarity count
   <ord>   <ord> <int>
 1     D      I1    42
 2     D     SI2  1370
 3     D     SI1  2083
 4     D     VS2  1697
 5     D     VS1   705
 6     D    VVS2   553
 7     D    VVS1   252
 8     D      IF    73
 9     E      I1   102
10     E     SI2  1713
# ... with 46 more rows
person Bobby    schedule 14.10.2017
comment
Увидел, что вы приняли ответ, но затем я внес небольшую правку в грамматику и заметил, что зеленый флажок исчез. Вы можете принять его снова, если хотите. Дайте мне знать, если у вас есть какие-либо вопросы о том, как это работает. - person Bobby; 14.10.2017