在现有行之间添加具有特定值的行

时间:2019-01-18 21:00:11

标签: r dplyr purrr

我有冰球数据,称为Lines <- " A 5 9 2 6 A 13 8 A 4 8 3 10 6 B 12 5 11 B 7 1 17 6 8 1" DF <- read.table(text = Lines, as.is = TRUE, fill = TRUE) names(DF)[1] <- "Class"

df

如何在每一行之后创建行,剩下57 * 2(114行),但是新创建的行中的值取决于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)) 列。

  • 如果event_rinkside等于event_rinkside,那么,我想将R插入82并将coords_x插入0
  • 如果coords_y等于event_rinkside,那么,我想将L插入-82并将coords_x插入0

我认为解决此SO question的方法是一个很好的起点,但是我不知道如何结合自己的条件:

这是我正在谈论的解决方案:

coords_y

4 个答案:

答案 0 :(得分:2)

这是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;如果event_rinkside == "L",则该值乘以-1,否则乘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

答案 1 :(得分:0)

我对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)

您可以将新创建​​的行插入循环中,也可以在知道它们全部为偶数索引后添加它们。

答案 2 :(得分:0)

这类似于Sven的回答,使用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_else s。

答案 3 :(得分:0)

我的尝试,已经非常类似于其他答案了,

import keras 
import matplotlib.pyplot as plt

x=np.random.uniform(0,10,size=41).reshape(-1,1)
x[::2]*=-1
y=x[1:]
x=x[:-1]
train_gen = keras.preprocessing.sequence.TimeseriesGenerator(
        x,
        y,
        length=1,
        sampling_rate=1,
        batch_size=1,
        shuffle=False
    )

model = keras.models.Sequential()
model.add(keras.layers.LSTM(100, input_shape=(1, 1), return_sequences=False))
model.add(keras.layers.Dense(1))


model.compile(
    loss="mse",
    optimizer="rmsprop",
    metrics=[keras.metrics.mean_squared_error]
)
model.optimizer.lr/=.1

history = model.fit_generator(
    train_gen,
    epochs=20,
    steps_per_epoch=100
)