#r #dplyr
#r #dplyr
Вопрос:
Скажем, если у нас есть фрейм данных, выглядящий так, как показано ниже:
a b c d
22 18 25 9
12 24 6 18
37 8 22 25
24 19 12 27
Я хотел бы создать два новых столбца из этих:
a) Один столбец, хранящий имя столбца, в котором каждая строка получает свое наибольшее значение.
б) Другой столбец, хранящий его наибольшее значение.
Другими словами, мой желаемый результат будет выглядеть следующим образом:
a b c d max_col max_val
22 18 25 9 c 25
12 24 6 18 b 24
37 8 22 25 a 37
24 19 12 27 d 27
Как я должен сделать, чтобы получить это?
Ответ №1:
Работает ли это:
> library(dplyr)
> df %>% rowwise() %>% mutate(max_col = names(df)[which.max(c_across(a:d))], max_val = max(c_across(a:d)))
# A tibble: 4 x 6
# Rowwise:
a b c d max_col max_val
<dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 22 18 25 9 c 25
2 12 24 6 18 b 24
3 37 8 22 25 a 37
4 24 19 12 27 d 27
>
Ответ №2:
Это также может быть достигнуто изменением формы данных и слиянием:
library(tidyverse)
#Code
newdf <- df %>% mutate(id=row_number()) %>%
left_join(
df %>% mutate(id=row_number()) %>%
pivot_longer(-id) %>%
group_by(id) %>% filter(value==max(value)[1]) %>%
rename(max_col=name,max_val=value)
) %>% select(-id)
Вывод:
a b c d max_col max_val
1 22 18 25 9 c 25
2 12 24 6 18 b 24
3 37 8 22 25 a 37
4 24 19 12 27 d 27
Некоторые используемые данные:
#Data
df <- structure(list(a = c(22L, 12L, 37L, 24L), b = c(18L, 24L, 8L,
19L), c = c(25L, 6L, 22L, 12L), d = c(9L, 18L, 25L, 27L)), class = "data.frame", row.names = c(NA,
-4L))
Ответ №3:
Мы можем сделать это эффективным векторизованным способом с max.col
помощью from base R
— получает индекс позиции максимального значения в строке, который используется для извлечения соответствующего имени столбца [
и pmax
возврата max
значения для каждой строки
mcol <- names(df)[max.col(df, 'first')]
mval <- do.call(pmax, df)
df[c('max_col', 'max_val')] <- list(mcol, mval)
-вывод
df
# a b c d max_col max_val
#1 22 18 25 9 c 25
#2 12 24 6 18 b 24
#3 37 8 22 25 a 37
#4 24 19 12 27 d 27
Или используя tidyverse
, мы можем использовать то же max.col
самое и pmax
для получения имен столбцов с максимальным значением в строке и максимальным значением строки
library(dplyr)
library(purrr)
df %>%
mutate(max_col = names(cur_data())[max.col(cur_data(), 'first')],
max_val = invoke(pmax, select(cur_data(), where(is.numeric))))
-вывод
# a b c d max_col max_val
# 1 22 18 25 9 c 25
# 2 12 24 6 18 b 24
# 3 37 8 22 25 a 37
# 4 24 19 12 27 d 27
данные
df <- structure(list(a = c(22L, 12L, 37L, 24L), b = c(18L, 24L, 8L,
19L), c = c(25L, 6L, 22L, 12L), d = c(9L, 18L, 25L, 27L)),
class = "data.frame", row.names = c(NA,
-4L))
Ответ №4:
Вот еще один базовый параметр R
inds <- max.col(df)
df <- cbind(df,
max_col = names(df)[inds],
max_val = df[cbind(seq_along(inds), inds)]
)
что дает
a b c d max_col max_val
1 22 18 25 9 c 25
2 12 24 6 18 b 24
3 37 8 22 25 a 37
4 24 19 12 27 d 27