как получить количество общих и неподеленных True и false во всех строках - PullRequest
2 голосов
/ 20 мая 2019

У меня есть такие данные

df<- structure(list(rowid = 1:12, P = c(TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE), T = c(TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE), 
    X = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, 
    FALSE, TRUE, TRUE)), row.names = c(NA, -12L), class = c("tbl_df", 
"tbl", "data.frame"))

Я пытаюсь получить, когда все строки равны True, False или смешаны.

Так что в этом случае это будет так

AllTure  AllFalse  Mixed 
9          0        2

Ответы [ 4 ]

6 голосов
/ 20 мая 2019

С dplyr вы можете сделать:

df %>%
 summarise(AllTure = sum(rowSums(.[2:4]) == 3),
           AllFalse = sum(rowSums(.[2:4]) == 0),
           Mixed = n() - (AllFalse + AllTure))

  AllTure AllFalse Mixed
    <int>    <int> <int>
1       9        0     3
5 голосов
/ 20 мая 2019

Опция будет

table(rowSums(df[-1]))

Чтобы получить ожидаемые метки, мы можем преобразовать его в factor с levels указанным

s1 <- rowSums(df[-1])
table(factor(replace(s1, !s1  %in% c(0, 3), 1), levels = c(0, 1, 3), 
      labels = c("AllFalse", "Mixed", "AllTrue")))
# AllFalse    Mixed  AllTrue 
#      0        3        9 

ПРИМЕЧАНИЕ: оба решения используют только base R


Если он нам нужен в tidyverse, опция без изменения формы или выполнения одних и тех же вычислений несколько раз, получите сумму строк с помощью reduce, затем преобразуйте столбец 'Sum' в factor с помощью levels задайте и получите частоту с count

library(tidyverse)    
df %>%
   transmute(Sum = reduce(.[-1], `+`)) %>% 
   mutate(Sum = factor(recode(Sum, `3` = 'AllTrue', `0`= 'AllFalse', 
       .default = 'Mixed'),
   levels = c("AllTrue", 'AllFalse', 'Mixed'))) %>% 
   count(Sum, .drop = FALSE)
# A tibble: 3 x 2
#  Sum          n
#  <fct>    <int>
#1 AllTrue      9
#2 AllFalse     0
#3 Mixed        3
3 голосов
/ 20 мая 2019

Другой вариант с cut заключается в создании breaks через соответствующие интервалы и назначении labels соответственно.

table(cut(rowSums(df[-1]), breaks = c(-Inf,0, ncol(df) - 2, Inf),
      labels = c("AllFalse", "Mixed", "AllTrue")))

#AllFalse    Mixed  AllTrue 
#       0        3        9 

В идеале значение break должно быть ncol(df) - 1, мы используем ncol(df) - 2 здесь, потому что мы хотим игнорировать первый столбец из расчета.

2 голосов
/ 20 мая 2019

В общем, я думаю, что решения rowSums лучше. Но мне часто нравится преобразовывать длинные данные, чтобы сделать операции более гибкими, например, не жестко программировать, какие столбцы суммировать. Я бы также добавил, что вы можете захотеть сохранить количество столбцов, с которыми вы сопоставляете (в данном случае, 3) в переменной, снова, чтобы избежать жесткого кодирования. Компромисс для гибкости заключается в том, что это немного избыточно, с 2 вызовами summarise функций.

library(dplyr)
library(tidyr)

n <- ncol(df) - 1
df %>%
  gather(key, value, -rowid) %>%
  group_by(rowid) %>%
  summarise(all_true = sum(sum(value) == n),
            all_false = sum(sum(value) == 0),
            mixed = sum(!sum(value) %in% c(0, n))) %>%
  summarise_at(vars(-rowid), sum)
#> # A tibble: 1 x 3
#>   all_true all_false mixed
#>      <int>     <int> <int>
#> 1        9         0     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...