Как посчитать количество столбцов с одним значением? - PullRequest
2 голосов
/ 26 июня 2019

У меня есть набор данных, в котором столбцы символов имеют только одно значение - имя самого столбца.Каждая строка является наблюдением, и я хочу подсчитать, сколько таких столбцов существует для каждой строки.

Например:

id multi_value_col single_value_col_1 single_value_col_2
1  A               single_value_col_1 
2  D2              single_value_col_1 single_value_col_2
3  Z6                                 single_value_col_2

Мне бы хотелось добавить столбец, который подсчитывает количество столбцов с одним значением в строке.Примерно так:

id multi_value_col single_value_col_1 single_value_col_2  count
1  A               single_value_col_1                     1 
2  D2              single_value_col_1 single_value_col_2  2
3  Z6                                 single_value_col_2  1

Моя первоначальная идея состояла в том, чтобы использовать mutate_if и n_distinct, заменив строку на TRUE, которая затем может быть использована в mutate с rowSums:

data %>% 
 mutate_if(~n_distinct(.) == 1, TRUE, .) %>%
 mutate(count = rowSums???)

Однако я не могу заставить работать mutate_if, и я также не уверен насчет команды rowSums - есть ли операция sum_if TRUE, доступная для строк?

Ответы [ 2 ]

3 голосов
/ 26 июня 2019

Если мы проверяем имена столбцов, то

library(tidyverse)
data %>%
    mutate(count = pmap_int(.[-1], ~ {x1 <- c(...)
                 sum(x1 == names(x1))} ))
#  id multi_value_col single_value_col_1 single_value_col_2 count
#1  1               A single_value_col_1                        1
#2  2              D2 single_value_col_1 single_value_col_2     2
#3  3              Z6                    single_value_col_2     1

Или в base R

rowSums(data[-1] == names(data)[-1][col(data[-1])])

Если у набора данных есть NA, просто измените его на

rowSums(data[-1] == names(data)[-1][col(data[-1])], na.rm = TRUE)

Другие варианты, предложенные @thelatemail, включают транспонирование выбранных столбцов и выполнение colSums на логической матрице

nms <- names(data)[nm1]
colSums(t(data[nms]) == nms)

Или с Reduce

Reduce(`+`, Map(`==`, data[nms], nms))

Если целью является подсчет на основе непробелов, в base R мы создаем логическую матрицу с интересующими столбцами и делаем rowSums для нее

nm1 <- grep("single_value", names(data))
data$count <-  rowSums(data[nm1] != "")

С dplyr

library(dplyr)
data %>% 
    mutate(count = rowSums(.[nm1] != ""))
#  id multi_value_col single_value_col_1 single_value_col_2 count
#1  1               A single_value_col_1                        1
#2  2              D2 single_value_col_1 single_value_col_2     2
#3  3              Z6                    single_value_col_2     1

данные

data <- structure(list(id = 1:3, multi_value_col = c("A", "D2", "Z6"), 
    single_value_col_1 = c("single_value_col_1", "single_value_col_1", 
    ""), single_value_col_2 = c("", "single_value_col_2", "single_value_col_2"
    )), row.names = c(NA, -3L), class = "data.frame")
1 голос
/ 26 июня 2019

В зависимости от того, есть ли у вас NA в ваших данных или пустых ячейках, вы можете использовать один из следующих базовых подходов R, где мы сначала находим столбцы только с одним уникальным значением, а затем подсчитываем непустые или непустые ячейки за строку в этих соответствующих столбцах.

Если у вас NA

cols <- which(sapply(df, function(x) length(unique(na.omit(x)))) == 1)
df$count <- rowSums(!is.na(df[cols]))

df
#  id multi_value_col single_value_col_1 single_value_col_2 count
#1  1               A single_value_col_1               <NA>     1
#2  2              D2 single_value_col_1 single_value_col_2     2
#3  3              Z6               <NA> single_value_col_2     1

Если у вас есть пустые ячейки

cols <- which(sapply(df, function(x) length(unique(x[x!=""]))) == 1)
df$count <- rowSums(df[cols] != "")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...