Добавить строки с конкретными значениями между существующими строками - PullRequest
0 голосов
/ 19 января 2019

У меня есть хоккейные данные, которые называются df

structure(list(event_index = 1:57, coords_x = c(80, 53, 31, -56, 
-34, -33, -40, 30, -66, -36, 45, 17, -6, 47, -51, -31, -69, -86, 
-70, 80, 65, -76, -71, 81, -57, 80, 75, 77, -71, -40, -83, 62, 
77, 76, NA, -61, 69, -45, 68, 31, 58, 61, 80, 34, 80, -85, -37, 
-57, 76, 14, 49, -82, -34, -36, -83, -84, -55), coords_y = c(-1, 
14, -30, 17, 26, -23, -37, 17, -32, -18, 25, 17, -38, 21, 28, 
22, 17, 13, 10, -37, -17, 9, 18, -11, 21, -7, 3, 3, -38, 31, 
8, -30, -2, 4, NA, -5, 15, 10, -30, -34, 20, 27, -4, 8, -18, 
19, 32, -21, 0, 40, -4, -30, -24, -28, -2, -3, 34), event_rinkside = c("R", 
"R", "R", "L", "L", "L", "L", "R", "L", "L", "R", "N", "N", "R", 
"L", "L", "L", "L", "L", "R", "R", "L", "L", "R", "L", "R", "R", 
"R", "L", "L", "L", "R", "R", "R", NA, "L", "R", "L", "R", "R", 
"R", "R", "R", "R", "R", "L", "L", "L", "R", "N", "R", "L", "L", 
"L", "L", "L", "L")), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -57L))

Как мне создавать строки после каждой строки, оставляя мне 57 * 2 (114 строк), но значения в моих вновь созданных строках зависят от столбца event_rinkside.

  • Если event_rinkside равно R, я хочу вставить 82 в coords_x и 0 в coords_y.
  • Если event_rinkside равно L, я хочу вставить -82 в coords_x и 0 в coords_y.

Мне кажется, что решение этого ТАКОГО вопроса - хорошая отправная точка, но я не знаю, как учесть мои собственные условия:

Вот решение, о котором я говорю:

library(purrr)
df %>%
  group_by(id) %>%
  map_dfr(rbind, NA) %>%
  mutate(id = rep(df$id, each = 2))

Ответы [ 4 ]

0 голосов
/ 19 января 2019

Моя попытка, которая уже очень похожа на другие ответы

df <- df[rep(1:nrow(df), each = 2),] ## Create a duplicate row after each row

df[seq(2,nrow(df),2),] <- df[seq(2,nrow(df),2),] %>% mutate(coords_x = case_when(event_rinkside == "R" ~ 82,
                                                        event_rinkside == "L" ~ -82,
                                                        TRUE ~ coords_x),
                                   coords_y = case_when(event_rinkside == "R" ~ 0,
                                                        event_rinkside == "L" ~ 0,
                                                        TRUE ~ coords_y)
)
0 голосов
/ 19 января 2019

Вот решение с dplyr:

library(dplyr)

df %>%
  mutate(coords_x = 82 * ifelse(event_rinkside == "L", -1, 1),
         coords_y = 0) %>%
  rbind(df, .) %>%
  arrange(event_index)

Как это работает:

На первом шаге mutate используется для изменения неназначенной копии df. Столбец coords_x получает значение 82; значение умножается на -1, если event_rinkside == "L", и 1 в противном случае. Столбец coords_y получает значение 0.

На следующем шаге неизмененный исходный кадр данных df и его текущая неназначенная и измененная копия объединяются с rbind. Здесь . представляет результат шага mutate, описанного выше. Результат rbind имеет строки исходной версии над строками модифицированной версии.

На последнем шаге arrange используется для сортировки строк по значениям event_index. Таким образом, за каждой исходной строкой непосредственно следует соответствующая измененная строка.

Результат:

# A tibble: 114 x 4
   event_index coords_x coords_y event_rinkside
         <int>    <dbl>    <dbl> <chr>         
 1           1       80       -1 R             
 2           1       82        0 R             
 3           2       53       14 R             
 4           2       82        0 R             
 5           3       31      -30 R             
 6           3       82        0 R             
 7           4      -56       17 L             
 8           4      -82        0 L             
 9           5      -34       26 L             
10           5      -82        0 L             
# … with 104 more rows
0 голосов
/ 19 января 2019

Это похоже на ответ Свена, использующий case_when для различения возможностей в event_rinkside:

new_df <- df %>% bind_rows(
  df %>% mutate(
    coords_x = case_when(
      event_rinkside == 'R' ~  82,
      event_rinkside == 'L' ~ -82,
      TRUE                  ~ coords_x
    ),
    coords_y = case_when(
      event_rinkside == 'R' ~ 0,
      event_rinkside == 'L' ~ 0,
      TRUE                  ~ coords_y
    )
  )
) %>% arrange(
  event_index
)

Если вы знаете диапазоны ваших переменных, это можно упростить до if_elses.

0 голосов
/ 19 января 2019

Я не слишком знаком с r, мой алгоритм должен работать независимо от этого. Вы хотите сдвинуть строку до строки 2n-1. Я хотел бы создать второй массив и вручную разместить их в определенных индексах.

какой-то псевдокод для вас (я обычно пишу на python, так что мой псевдокод показывает его)

reinsert(list):
   array_out = [len(list)*2,len(list[0]) // initialize to the desired dimensions 
   array_out[0] = list[0]  /// manually insert first row cause math
   for n in range(0,len(list)):
      array_out[2n-1] = list[n] 
      array_out[2n] = event_rinkside // make a function call or make an ifthen clause to do you logic
   return(array_out)

Вы можете вставить вновь созданные строки в цикл или добавить их после того, как факт, зная, что все они будут иметь четные индексы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...