Создайте столбец с условными значениями, которые отражают максимальное значение в третьем столбце.

Вопрос или проблема

Я пытаюсь добавить столбец в датафрейм на основе сложного условия, и не могу найти посты, которые соответствуют тому, что я пытаюсь сделать. У меня есть данные следующего типа с тремя категориальными столбцами (“trial”, “word”, “point”) и одним непрерывным столбцом (“value”):

    trial  word  point value
1  trial1 word1 point1   337
2  trial1 word1 point2   105
3  trial1 word1 point3   289
4  trial1 word1 point4   190
5  trial1 word2 point1   167
6  trial1 word2 point2   223
7  trial1 word2 point3   384
8  trial1 word2 point4   143
9  trial2 word1 point1   179
10 trial2 word1 point2   101
11 trial2 word1 point3   122
12 trial2 word1 point4   213
13 trial2 word3 point1   409
14 trial2 word3 point2   221
15 trial2 word3 point3   582
16 trial2 word3 point4   178

Что я хочу знать, так это для данного trial, для данного word, какой point соответствует наивысшему value? А затем я хочу скопировать эту метку point в новый столбец для каждой строки для этого word. Вот как должен выглядеть новый столбец (max_point):

    trial  word  point value max_point
1  trial1 word1 point1   337    point1
2  trial1 word1 point2   105    point1
3  trial1 word1 point3   289    point1
4  trial1 word1 point4   190    point1
5  trial1 word2 point1   167    point3
6  trial1 word2 point2   223    point3
7  trial1 word2 point3   384    point3
8  trial1 word2 point4   143    point3
9  trial2 word1 point1   179    point4
10 trial2 word1 point2   101    point4
11 trial2 word1 point3   122    point4
12 trial2 word1 point4   213    point4
13 trial2 word3 point1   409    point3
14 trial2 word3 point2   221    point3
15 trial2 word3 point3   582    point3
16 trial2 word3 point4   178    point3

Итак, чтобы переформулировать, max_point представляет, какой point имеет наивысшее value для данного word в данном trial. Например, в trial1 word1 (первые 4 строки) из 4 точек, point1 имеет наивысшее значение (337), поэтому max_point имеет метку “point1” для каждой из 4 строк для этого слова.

Некоторые посты спрашивают, как вывести максимальное значение в новый столбец на основе условия, но не как вывести категориальную метку соответствующую максимальному значению. Как я могу это сделать?

Пожалуйста, дайте мне знать, если я могу предложить какое-либо пояснение, и спасибо!

С помощью data.table:

library(data.table)

dt[,max_point := point[which.max(value)], .(trial, word)][]
#>      trial   word  point value max_point
#>     <char> <char> <char> <int>    <char>
#>  1: trial1  word1 point1   337    point1
#>  2: trial1  word1 point2   105    point1
#>  3: trial1  word1 point3   289    point1
#>  4: trial1  word1 point4   190    point1
#>  5: trial1  word2 point1   167    point3
#>  6: trial1  word2 point2   223    point3
#>  7: trial1  word2 point3   384    point3
#>  8: trial1  word2 point4   143    point3
#>  9: trial2  word1 point1   179    point4
#> 10: trial2  word1 point2   101    point4
#> 11: trial2  word1 point3   122    point4
#> 12: trial2  word1 point4   213    point4
#> 13: trial2  word3 point1   409    point3
#> 14: trial2  word3 point2   221    point3
#> 15: trial2  word3 point3   582    point3
#> 16: trial2  word3 point4   178    point3

Данные:

dt <- fread(input = "id    trial  word  point value
            1  trial1 word1 point1   337
            2  trial1 word1 point2   105
            3  trial1 word1 point3   289
            4  trial1 word1 point4   190
            5  trial1 word2 point1   167
            6  trial1 word2 point2   223
            7  trial1 word2 point3   384
            8  trial1 word2 point4   143
            9  trial2 word1 point1   179
            10 trial2 word1 point2   101
            11 trial2 word1 point3   122
            12 trial2 word1 point4   213
            13 trial2 word3 point1   409
            14 trial2 word3 point2   221
            15 trial2 word3 point3   582
            16 trial2 word3 point4   178")[,id := NULL]

С помощью dplyr

library(dplyr)

df |>
  mutate(max_point = point[which.max(value)],
         .by = c(trial, word))
#> # A tibble: 16 × 5
#>    trial  word  point  value max_point
#>    <chr>  <chr> <chr>  <int> <chr>    
#>  1 trial1 word1 point1   337 point1   
#>  2 trial1 word1 point2   105 point1   
#>  3 trial1 word1 point3   289 point1   
#>  4 trial1 word1 point4   190 point1   
#>  5 trial1 word2 point1   167 point3   
#>  6 trial1 word2 point2   223 point3   
#>  7 trial1 word2 point3   384 point3   
#>  8 trial1 word2 point4   143 point3   
#>  9 trial2 word1 point1   179 point4   
#> 10 trial2 word1 point2   101 point4   
#> 11 trial2 word1 point3   122 point4   
#> 12 trial2 word1 point4   213 point4   
#> 13 trial2 word3 point1   409 point3   
#> 14 trial2 word3 point2   221 point3   
#> 15 trial2 word3 point3   582 point3   
#> 16 trial2 word3 point4   178 point3

Данные

df <- structure(list(trial = c("trial1", "trial1", "trial1", "trial1", 
                               "trial1", "trial1", "trial1", "trial1", "trial2", "trial2", "trial2", 
                               "trial2", "trial2", "trial2", "trial2", "trial2"), word = c("word1", 
                                                                                           "word1", "word1", "word1", "word2", "word2", "word2", "word2", 
                                                                                           "word1", "word1", "word1", "word1", "word3", "word3", "word3", 
                                                                                           "word3"), point = c("point1", "point2", "point3", "point4", "point1", 
                                                                                                               "point2", "point3", "point4", "point1", "point2", "point3", "point4", 
                                                                                                               "point1", "point2", "point3", "point4"), value = c(337L, 105L, 
                                                                                                                                                                  289L, 190L, 167L, 223L, 384L, 143L, 179L, 101L, 122L, 213L, 409L, 
                                                                                                                                                                  221L, 582L, 178L)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
                                                                                                                                                                                                                                              -16L))

Ответ или решение

Чтобы добавить в ваш датафрейм новый столбец с условными значениями, отражающими максимальное значение в третьем столбце, вы можете воспользоваться библиотеками data.table или dplyr в языке R. Выявление максимального значения и соответствующего ему ярлыка (в данном случае point) можно реализовать несколькими способами. Рассмотрим оба метода.

Использование data.table

  1. Сначала необходимо загрузить библиотеку data.table и создать датафрейм с вашими данными:
    
    library(data.table)

dt <- fread(input = "trial word point value
trial1 word1 point1 337
trial1 word1 point2 105
trial1 word1 point3 289
trial1 word1 point4 190
trial1 word2 point1 167
trial1 word2 point2 223
trial1 word2 point3 384
trial1 word2 point4 143
trial2 word1 point1 179
trial2 word1 point2 101
trial2 word1 point3 122
trial2 word1 point4 213
trial2 word3 point1 409
trial2 word3 point2 221
trial2 word3 point3 582
trial2 word3 point4 178")[, id := NULL]


2. Теперь мы можем добавить новый столбец `max_point`, который будет содержать наименования `point`, соответствующие максимальным значениям `value` для каждой комбинации `trial` и `word`:
```R
dt[, max_point := point[which.max(value)], by = .(trial, word)][]

В результате получим:

    trial   word  point value max_point
 1: trial1  word1 point1   337    point1
 2: trial1  word1 point2   105    point1
 3: trial1  word1 point3   289    point1
 4: trial1  word1 point4   190    point1
 5: trial1  word2 point1   167    point3
 6: trial1  word2 point2   223    point3
 7: trial1  word2 point3   384    point3
 8: trial1  word2 point4   143    point3
 9: trial2  word1 point1   179    point4
10: trial2  word1 point2   101    point4
11: trial2  word1 point3   122    point4
12: trial2  word1 point4   213    point4
13: trial2  word3 point1   409    point3
14: trial2  word3 point2   221    point3
15: trial2  word3 point3   582    point3
16: trial2  word3 point4   178    point3

Использование dplyr

  1. Аналогично, сначала загружаем библиотеку dplyr и создаем датафрейм:
    
    library(dplyr)

df <- data.frame(
trial = c("trial1", "trial1", "trial1", "trial1",
"trial1", "trial1", "trial1", "trial1",
"trial2", "trial2", "trial2", "trial2",
"trial2", "trial2", "trial2", "trial2"),
word = c("word1", "word1", "word1", "word1",
"word2", "word2", "word2", "word2",
"word1", "word1", "word1", "word1",
"word3", "word3", "word3", "word3"),
point = c("point1", "point2", "point3", "point4",
"point1", "point2", "point3", "point4",
"point1", "point2", "point3", "point4",
"point1", "point2", "point3", "point4"),
value = c(337, 105, 289, 190, 167, 223, 384, 143,
179, 101, 122, 213, 409, 221, 582, 178)
)


2. Теперь используем функцию `mutate` для добавления нового столбца:
```R
df <- df %>%
  mutate(max_point = point[which.max(value)], .by = c(trial, word))

После выполнения этого кода, датафрейм будет выглядеть следующим образом:

   trial   word  point value max_point
1 trial1 word1 point1   337    point1
2 trial1 word1 point2   105    point1
3 trial1 word1 point3   289    point1
4 trial1 word1 point4   190    point1
5 trial1 word2 point1   167    point3
6 trial1 word2 point2   223    point3
7 trial1 word2 point3   384    point3
8 trial1 word2 point4   143    point3
9 trial2 word1 point1   179    point4
10 trial2 word1 point2   101    point4
11 trial2 word1 point3   122    point4
12 trial2 word1 point4   213    point4
13 trial2 word3 point1   409    point3
14 trial2 word3 point2   221    point3
15 trial2 word3 point3   582    point3
16 trial2 word3 point4   178    point3

Заключение

Оба предложенных подхода позволяют эффективно добавить новый столбец max_point в ваш датафрейм, который будет содержать наименования point, соответствующие максимальным значениям value. Выбор между data.table и dplyr зависит от ваших предпочтений в работе с данными и специфики ваших задач.

Оцените материал
Добавить комментарий

Капча загружается...