R: свернуть строки и изменить значение в соответствии с условием во фрейме данных - PullRequest
1 голос
/ 27 марта 2020

У меня есть набор данных:

structure(list(num = c(12L, 12L), code = structure(1:2, .Label = c("a", "b"), class = "factor"), ranking = c(2414.5, 2414.5), bottom = c(-0.0153795976572657, -0.00651997615327495), previous = c(0.00121016455715892, -0.000166609624290187), of_all_previous = c(-0.000570973882726524, -0.000771377162183913)), row.names = c(NA, -2L), class = "data.frame")

Я хотел бы свернуть две строки в соответствии с num и ranking, так как они одинаковые, но меняются code в соответствии с условиями, в которых значения двух строк для столбцов bottom, previous и of_all_previous должны сравниваться последовательно (то есть: если они равны, переходите к следующему столбцу, как в bottom -> previous -> of_all_previous) и выберите code, значение которого выше.

В случае предоставленных данных выборки, code b, поскольку -0.0065199761532749503 > -0.0153795976572656777 в столбце bottom.

Если бы они были равны, тогда нужно было бы посмотреть previous столбцы.

Я думаю, что, возможно, dplyr может использовать %>%, чтобы свернуть строки, но я не могу найти, как изменить строки одновременно в соответствии с условиями.

Я ожидаю, что результат будет выглядеть примерно так:

            num   code ranking 
1            12    a  2414      

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 28 марта 2020

Одним из подходов может быть group_by и num, и ranking для просмотра строк, которые имеют одинаковые значения и должны быть свернуты.

Тогда arrange (сортировка) будет по убыванию Закажите столбцы, в которых производится сравнение, включая bottom previous и of_all_previous. Когда это будет сделано, верхняя строка в отсортированных данных будет рассматривать столбцы для сравнения при наличии связей.

Наконец, вы можете создать final_code с first(code) на основе сортировки.

library(tidyverse)

df %>%
  group_by(num, ranking) %>%
  arrange(-bottom, -previous, -of_all_previous) %>%
  mutate(final_code = ifelse(n() > 1, as.character(first(code)), as.character(code))) %>%
  slice(1) %>%
  select(num, code, ranking)
0 голосов
/ 27 марта 2020

Возможно, мы можем повернуть в «длинный» формат и slice строку

library(dplyr)
library(tidyr)
df1 %>%
   pivot_longer(cols = bottom:of_all_previous) %>%
  group_by(num, ranking, name) %>%
  slice(which.max(value)) %>% 
  ungroup %>% 
  slice(1)
# A tibble: 1 x 5
#    num code  ranking name      value
#  <int> <fct>   <dbl> <chr>     <dbl>
#1    12 b       2414. bottom -0.00652
...