Как заменить уникальные значения индексом с помощью функции mutate? - PullRequest
1 голос
/ 22 апреля 2019

Я хотел бы заменить уникальные значения индексным числом, используя dplyr :: mutate.

Я группируюсь по нескольким переменным для доступа к соответствующему подмножеству моего фрейма данных.

  head(df)
       group start_time end_time
  1    group1       0   0.4
  2    group1       0   0.4
  3    group1      0   0.4
  4    group1     0.4   0.8
  5    group1     0.4   0.8
  6    group2     0.0   0.4
  7    group2     0.4   0.8
  8    group2     0.8   1.02

I group_by 'group', а затем 'start_time.'Иногда у данной группы есть только одно start_time, иногда два start_time или иногда три.Мне нужно создать новую переменную, «idx» для каждого уникального start_time.Но я не могу думать, как это сделать.

  new_df <- df %>% 
    group_by(group, start_time) %>% 
    mutate(idx = row_number()) %>%
    as.data.frame

Создание новой переменной с помощью row_number () не правильно.Это дает мне:

  idx
  1
  2
  3
  1
  2
  1
  1
  1

Но я хочу:

  idx
  1
  1
  1
  2
  2
  1
  2
  3

Я думал о замене каждого уникального значения в group_by числом?И повторять?

Ответы [ 3 ]

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

Мы можем использовать match после группировки по 'group'

library(tidyverse)
df %>% 
   group_by(group) %>%
   mutate(idx = match(start_time, unique(start_time)))
# A tibble: 8 x 4
# Groups:   group [2]
#  group  start_time end_time   idx
#  <chr>       <dbl>    <dbl> <int>
#1 group1        0       0.4      1
#2 group1        0       0.4      1
#3 group1        0       0.4      1
#4 group1        0.4     0.8      2
#5 group1        0.4     0.8      2
#6 group2        0       0.4      1
#7 group2        0.4     0.8      2
#8 group2        0.8     1.02     3

или другой вариант: group_indices

df %>% 
   group_split(group) %>%
   map_df(~ .x %>% 
                mutate(idx = group_indices(., start_time)))

ПРИМЕЧАНИЕ: если 'idx'необходимо создать за пределами 'group', затем удалить group_by step

ПРИМЕЧАНИЕ2: В примере с OP оба (с / без group_by) дают одинаковый вывод

2 голосов
/ 22 апреля 2019

На самом деле мы можем легко сделать это, используя тип коэффициента R.Переменная factor хранится в виде целых чисел, которые ссылаются на таблицу уровней, в которой хранятся фактические значения.Затем мы можем использовать as.integer или as.numeric для преобразования из коэффициента обратно в число.Когда вы это сделаете, таблица уровней будет потеряна, и у вас останутся только целые числа, которые ссылаются на нее;обычно это нежелательно (вам нужны ваши фактические значения, а не закодированные значения), но в этом случае это желательно, поскольку идентичные значения будут кодироваться с одинаковым номером:

df <- structure(list(group = c("group1", "group1", "group1", "group1", 
"group1", "group2", "group2", "group2"), start_time = c(0, 0, 
0, 0.4, 0.4, 0, 0.4, 0.8), end_time = c(0.4, 0.4, 0.4, 0.8, 0.8, 
0.4, 0.8, 1.02)), class = "data.frame", row.names = c(NA, -8L
))

df %>%
    mutate(idx = as.integer(factor(start_time)))

   group start_time end_time idx
1 group1        0.0     0.40   1
2 group1        0.0     0.40   1
3 group1        0.0     0.40   1
4 group1        0.4     0.80   2
5 group1        0.4     0.80   2
6 group2        0.0     0.40   1
7 group2        0.4     0.80   2
8 group2        0.8     1.02   3

В качестве дополнительного преимущества это работает толькоа также в базе R:

df$idx <- as.integer(factor(df$start_time))
df
   group start_time end_time idx
1 group1        0.0     0.40   1
2 group1        0.0     0.40   1
3 group1        0.0     0.40   1
4 group1        0.4     0.80   2
5 group1        0.4     0.80   2
6 group2        0.0     0.40   1
7 group2        0.4     0.80   2
8 group2        0.8     1.02   3
1 голос
/ 22 апреля 2019

Другой вариант - data.table::frank (сокращение от быстрого ранга)

df %>% 
   group_by(group) %>%
   mutate(idx = data.table::frank(start_time, ties.method = 'dense'))

# # A tibble: 8 x 4
# # Groups:   group [2]
#   group  start_time end_time   idx
#   <chr>       <dbl>    <dbl> <int>
# 1 group1        0       0.4      1
# 2 group1        0       0.4      1
# 3 group1        0       0.4      1
# 4 group1        0.4     0.8      2
# 5 group1        0.4     0.8      2
# 6 group2        0       0.4      1
# 7 group2        0.4     0.8      2
# 8 group2        0.8     1.02     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...