Получение максимального значения из фрейма данных из нескольких столбцов - PullRequest
1 голос
/ 16 апреля 2019

У меня есть набор данных, как показано ниже

Account eta1    eta2    eta3    eta4    eta6  grp  grp1
123       NA    0      0       1       NA     pol  tree
456       NA    NA     NA      NA       1     cal  tre
789       NA    NA     NA      0        2     pal   tre
111       NA    NA     NA      NA      NA     trol  tre

Я хочу, чтобы мой вывод выглядел следующим образом

ACC  eta  grp grp1
123   1  pol  tree
456   1  cal  tre
789   2  pal   tre
111  NA  trol  tre

Как мне добиться этого с помощью R

Ответы [ 4 ]

4 голосов
/ 16 апреля 2019

Попробуйте это:

do.call(pmax,c(df[grep("eta",names(df))],na.rm=TRUE))
#[1]  1  1  2 NA

DATA

df<-structure(list(Account = c(123L, 456L, 789L, 111L), eta1 = c(NA, 
NA, NA, NA), eta2 = c(0L, NA, NA, NA), eta3 = c(0L, NA, NA, NA
), eta4 = c(1L, NA, 0L, NA), eta6 = c(NA, 1L, 2L, NA), grp = c("pol", 
"cal", "pal", "trol"), grp1 = c("tree", "tre", "tre", "tre")), class = "data.frame", row.names = c(NA, 
-4L))
2 голосов
/ 16 апреля 2019

Другим способом будет использование dplyr:

library(dplyr)

df <- data.frame(stringsAsFactors = FALSE,
                 Account = c(123, 456, 789, 111),
                 eta1 = c(NA, NA, NA, NA),
                 eta2 = c(0, NA, NA, NA),
                 eta3 = c(0, NA, NA, NA),
                 eta4 = c(1, NA, 0, NA),
                 eta6 = c(NA, 1, 2, NA),
                 grp = c("pol", "cal", "pal", "trol"),
                 grp1 = c("tree", "tre", "tre", "tre"))

df %>%
  mutate(eta = pmax(eta1, eta2, eta3, eta4, eta6, na.rm = TRUE)) %>%
  select(Account, eta, grp, grp1)
0 голосов
/ 16 апреля 2019

Мне нравится подходить к таким проблемам с dplyr и tidyr, в частности, чтобы преобразовать данные в форму, которая хорошо масштабируется. Я обычно предпочитаю иметь переменные ETA в одном столбце, а не работать на eta1, eta2 и т. Д., Поэтому я ничего не пропускаю, и поэтому моя работа достаточно гибкая, чтобы добавлять или удалять столбцы.

Хитрая часть, как уже упоминали другие, получает максимум, даже если все значения NA. Я написал функцию, чтобы справиться с этим, где NA возвращается, если все значения NA.

library(dplyr)
library(tidyr)

max_or_na <- function(x) {
  if (all(is.na(x))) {
    NA
  } else {
    max(x, na.rm = T)
  }
}

df %>%
  gather(key = eta, value, starts_with("eta")) %>%
  group_by(Account, grp, grp1) %>%
  summarise(eta = max_or_na(value))
#> # A tibble: 4 x 4
#> # Groups:   Account, grp [4]
#>   Account grp   grp1    eta
#>     <int> <chr> <chr> <int>
#> 1     111 trol  tre      NA
#> 2     123 pol   tree      1
#> 3     456 cal   tre       1
#> 4     789 pal   tre       2

Затем вы можете разгруппировать и изменить порядок, как считаете нужным.

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

Применение max к числовым столбцам с правилом исключения.(Но решение @ nicola лучше.)

apply(dat[sapply(dat, is.numeric)], 1, 
      function(x) if (all(is.na(x))) NA else max(na.omit(x)))
# [1]  2  1  2 NA

Вы можете дополнительно обернуть это в пользовательскую функцию

row.max <- function(dat) {
  return(apply(dat[sapply(dat, is.numeric)], 1, 
        function(x) if (all(is.na(x))) NA else max(na.omit(x))))
}

с использованием:

dat <- transform(dat, max=row.max(dat))
#   Account eta1 eta2 eta3 eta4 eta6  grp grp1 max
# 1     123   NA    1    1    2   NA  pol tree   2
# 2     456   NA   NA   NA   NA    1  cal  tre   1
# 3     789   NA   NA   NA    1    2  pal  tre   2
# 4     111   NA   NA   NA   NA   NA trol  tre  NA

Данные

dat <- structure(list(Account = structure(c(2L, 3L, 4L, 1L), .Label = c("111", 
"123", "456", "789", "Account"), class = "factor"), eta1 = c(NA_real_, 
NA_real_, NA_real_, NA_real_), eta2 = c(1, NA, NA, NA), eta3 = c(1, 
NA, NA, NA), eta4 = c(2, NA, 1, NA), eta6 = c(NA, 1, 2, NA), 
    grp = structure(c(4L, 1L, 3L, 5L), .Label = c("cal", "grp", 
    "pal", "pol", "trol"), class = "factor"), grp1 = structure(c(3L, 
    2L, 2L, 2L), .Label = c("grp1", "tre", "tree"), class = "factor")), row.names = c(NA, 
-4L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...