Как group_by, а затем суммировать, какие строки имеют NA во всех столбцах - PullRequest
1 голос
/ 25 апреля 2019

Я не уверен, возможно ли это.Я хочу использовать суммирование для подсчета всех строк, которые имеют NA во всех столбцах, кроме group_by.Я могу сделать это, соединив все 5 условий, где у меня есть NO_OL_Percent =, затем я должен соединить каждый столбец с &.Если вы можете сделать это в SQL, я думаю, вы могли бы сделать это с помощью dplyr или purrr, но, похоже, никто в Интернете не пробовал этого.

Данные должны быть загружены здесь

Код ниже.Это работает, но неужели нет способа использовать функцию all для последней строки кода?Мне нужно сначала сделать group_by, и я не могу использовать filter_all в dplyr.

farmers_market = read.csv("Export.csv", stringsAsFactors = F, na.strings=c("NA","NaN", ""))

farmers_market %>% 
        select(c("Website", "Facebook", "Twitter", "Youtube", "OtherMedia", "State")) %>%
        group_by(State) %>%
        summarise(Num_Markets = n(),
                  FB_Percent = 100 - 100*sum(is.na(Facebook))/n(), 
                  TW_Percent = 100 - 100*sum(is.na(Twitter))/n(),
                  #fb=sum(is.na(Facebook)),
                  OL_Percent = 100 - 100*sum(is.na(Facebook) & is.na(Twitter))/n(),
                  NO_OL_Percent = 100 - 100*sum(is.na(Facebook) & is.na(Twitter) & is.na(Website) & is.na(Youtube) & is.na(OtherMedia))/n()
                  )

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Я удалил оператор select, так как мы суммируем, все равно будут выбраны только соответствующие столбцы. Создан вектор cols, из которого мы хотим вычислить NA с.

Сначала мы проверяем для каждой строки, имеет ли эта строка все значения NA в столбцах cols и присваиваем значение TRUE / FALSE новому столбцу all_NA. Затем мы group_by State и выполняем вычисление для остальных столбцов, как есть, но для NO_OL_Percent мы суммируем ALL_NA, чтобы получить общее число NA с на группу и разделить его на общее количество строк в группе. .

library(dplyr)

cols <- c("Website", "Facebook", "Twitter", "Youtube", "OtherMedia")

farmers_market %>% 
   mutate(all_NA = rowSums(is.na(.[cols])) == length(cols)) %>%
   group_by(State) %>%
   summarise(Num_Markets = n(),
             FB_Percent = 100 - 100*sum(is.na(Facebook))/n(), 
             TW_Percent = 100 - 100*sum(is.na(Twitter))/n(),
             OL_Percent = 100 - 100*sum(is.na(Facebook) & is.na(Twitter))/n(),
             NO_OL_Percent = 100 - 100*sum(all_NA)/n())


#    State                Num_Markets FB_Percent TW_Percent OL_Percent NO_OL_Percent
#    <chr>                      <int>      <dbl>      <dbl>      <dbl>         <dbl>
# 1 Alabama                      139       25.9       5.76       25.9          37.4
# 2 Alaska                        38       42.1      10.5        42.1          65.8
# 3 Arizona                       92       57.6      27.2        57.6          80.4
# 4 Arkansas                     111       52.3       4.50       52.3          61.3
# 5 California                   759       41.5      14.5        43.2          70.1
# 6 Colorado                     161       44.1       9.94       44.1          82.6
# 7 Connecticut                  157       33.8      12.1        33.8          53.5
# 8 Delaware                      36       61.1      11.1        61.1          83.3
# 9 District of Columbia          57       50.9      43.9        50.9          87.7
#10 Florida                      262       43.1       8.78       43.1          83.2
# … with 43 more rows

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

0 голосов
/ 25 апреля 2019

Прямой способ получить столбец Percent будет:

farmers_market %>% 
    select("Website", "Facebook", "Twitter", "Youtube", "OtherMedia", "State") %>%
    group_by(State) %>% 
    summarise_all(funs("Percent" = sum(is.na(.))/n()))

# A tibble: 53 x 6
#  State   Website_Percent Facebook_Percent Twitter_Percent Youtube_Percent OtherMedia_Percent
#  <chr>             <dbl>            <dbl>           <dbl>           <dbl>              <dbl>
#1 Alabama           0.727            0.741           0.942           0.993              0.964
#2 Alaska            0.447            0.579           0.895           1                  0.974

Чтобы добавить столбец num_markets, можно сделать следующее:

farmers_market %>% 
    select("Website", "Facebook", "Twitter", "Youtube", "OtherMedia", "State") %>%
    group_by(State) %>% 
    mutate(num_markets = n()) %>% 
    group_by(State, num_markets) %>% 
    summarise_all(funs("Percent" = sum(is.na(.))/n()))

# A tibble: 53 x 7
# Groups:   State [2]
#  State   num_markets Website_Percent Facebook_Percent Twitter_Percent Youtube_Percent OtherMedia_Percent
#  <chr>         <int>           <dbl>            <dbl>           <dbl>           <dbl>              <dbl>
#1 Alabama         139           0.727            0.741           0.942           0.993              0.964
#2 Alaska           38           0.447            0.579           0.895           1                  0.974
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...