Какое поле отличается с помощью dplyr? - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть следующие данные

df <- data.frame(val1=c(1.2,0.5,3.8,2.5,7.4),
                 val2=c(1.2,2.5,3.8,2.5,2.4),
                 val3=c(1.2,2.5,3.6,2.5,7.4),
                 val4=c(1.2,2.5,3.8,2.5,4.4),
                 val5=c(1.2,2.5,3.8,2.9,7.4))

Я бы хотел найти, какое поле отличается от остальных.Ожидается, что результат, как показано ниже, будет добавлен во фрейм данных

cbind(df,results = c("all_equal", "val1","val3","val5","morethan1"))

Есть ли способ сделать это простым способом?У меня есть обширный цикл, чтобы получить этот результат, который я не буду публиковать здесь.Я ищу быстрое решение, которое я пропустил (возможно, с помощью dplyr)

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Вот один вариант с tidyverse путем преобразования данных в «длинный» формат, применения условий для создания столбца «результат», а затем связывания столбца с исходным набором данных

library(tidyverse)
rownames_to_column(df, 'rn') %>% 
   gather(key, val, matches('^val')) %>% 
   group_by(rn) %>%
   mutate(Mode = Modes(val)) %>% 
   summarise(result = case_when(all(val == Mode) ~ "all_equal",
                           sum(val != Mode) > 1 ~ "morethan1",
                       TRUE ~ paste0("val", which(val != Mode), collapse=","))) %>% 
  select(result) %>% 
  bind_cols(df, .)
#  val1 val2 val3 val4 val5    result
#1  1.2  1.2  1.2  1.2  1.2 all_equal
#2  0.5  2.5  2.5  2.5  2.5      val1
#3  3.8  3.8  3.6  3.8  3.8      val3
#4  2.5  2.5  2.5  2.5  2.9      val5
#5  7.4  2.4  7.4  4.4  7.4 morethan1

.Modes функция

Modes <- function(x) {
  ux <- unique(x)
  tab <- tabulate(match(x, ux))
  ux[tab == max(tab)]
 }
0 голосов
/ 18 сентября 2018

Сначала определите функцию для расчета режима.Я использовал найденную здесь функцию: https://stackoverflow.com/a/8189441/7669809

Modes <- function(x) {
  ux <- unique(x)
  tab <- tabulate(match(x, ux))
  ux[tab == max(tab)]
}

После этого мы можем использовать следующий код для получения желаемого результата.

apply(df, 1, function(x){
  x_mode <- Modes(x)
  if (all(x == x_mode)){
    return("all_equal")
  } else if (sum(x != x_mode) > 1){
    return("morethan1")
  } else {
    ind <- which(x != x_mode)
    return(paste0("val", ind))
  }
})
# [1] "all_equal" "val1"      "val3"      "val5"      "morethan1"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...