Вычисление по строкам и запись результатов в столбец с именем переменной

#r

#r

Вопрос:

Я пытался вставить переменную и объединить с оставшимся именем столбца, но это всегда возвращает ошибку. Кроме того, я думаю, что я излишне усложняю выполнение различных циклов for и ретроактивно переименовываю строки.

В принципе, я хотел бы произвести вычитание значения в DELY_QTY столбце по строкам из всех WK_DIFF_XX значений по отдельности и записать результат в новый столбец DIFF_XX , при этом XX соответствует цифре WK_DIFF столбца.

 > str(df_full)
'data.frame':   959 obs. of  18 variables:
 $ DELY_DATE : Date, format: "2015-01-26" "2015-02-02" "2015-02-09" "2015-02-16" ...
 $ WK_DIFF_3 : int  37 40 72 30 41 36 63 28 19 8 ...
 $ WK_DIFF_4 : int  NA 40 72 31 44 35 57 28 19 6 ...
 $ WK_DIFF_5 : int  NA NA 73 35 43 33 57 27 24 6 ...
 $ WK_DIFF_6 : int  NA NA NA 37 48 35 57 27 31 14 ...
 $ WK_DIFF_7 : int  NA NA NA NA 52 39 49 39 39 25 ...
 $ WK_DIFF_8 : int  NA NA NA NA NA 47 53 41 36 25 ...
 $ WK_DIFF_9 : int  NA NA NA NA NA NA 51 42 34 30 ...
 $ WK_DIFF_10: int  NA NA NA NA NA NA NA 43 35 30 ...
 $ WK_DIFF_11: int  NA NA NA NA NA NA NA NA 35 30 ...
 $ WK_DIFF_12: int  NA NA NA NA NA NA NA NA NA 30 ...
 $ WK_DIFF_13: int  NA NA NA NA NA NA NA NA NA NA ...
 $ WK_DIFF_14: int  NA NA NA NA NA NA NA NA NA NA ...
 $ WK_DIFF_15: int  NA NA NA NA NA NA NA NA NA NA ...
 $ WK_DIFF_16: int  NA NA NA NA NA NA NA NA NA NA ...
 $ WK_DIFF_17: int  NA NA NA NA NA NA NA NA NA NA ...
 $ WK_DIFF_18: int  NA NA NA NA NA NA NA NA NA NA ...
 $ DELY_QTY  : int  82 62 57 57 67 57 53 70 70 60 ...
  

Хотя кажется, что некоторые из WK_DIFF столбцов пусты, они содержат значения в нижней части столбца.

 > dput(df_full[1:5, ])
structure(list(DELY_DATE = structure(c(16461, 16468, 16475, 16482, 
16489), class = "Date"), WK_DIFF_3 = c(37L, 40L, 72L, 30L, 41L
), WK_DIFF_4 = c(NA, 40L, 72L, 31L, 44L), WK_DIFF_5 = c(NA, NA, 
73L, 35L, 43L), WK_DIFF_6 = c(NA, NA, NA, 37L, 48L), WK_DIFF_7 = c(NA, 
NA, NA, NA, 52L), WK_DIFF_8 = c(NA_integer_, NA_integer_, NA_integer_, 
NA_integer_, NA_integer_), WK_DIFF_9 = c(NA_integer_, NA_integer_, 
NA_integer_, NA_integer_, NA_integer_), WK_DIFF_10 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_11 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_12 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_13 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_14 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_15 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_16 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_17 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), WK_DIFF_18 = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), DELY_QTY = c(82L, 
62L, 57L, 57L, 67L)), row.names = c(NA, 5L), class = "data.frame")
  

Я ценю предложение о правильном подходе к этому.

Ответ №1:

Вы можете использовать mutate() с across() помощью. Чтобы манипулировать новыми именами столбцов, вы можете использовать синтаксис спецификации клея в .names аргументе.

 library(dplyr)

df_full %>%
  mutate(across(starts_with("WK_DIFF"), ~ DELY_QTY - .x,
                .names = '{sub("WK_", "", col)}'))
  
  • Примечание: '{sub("WK_", "", col)}' преобразуется WK_DIFF_X в DIFF_X .

  • Описание .names :

    Спецификация склеивания, которая описывает, как называть выходные столбцы. Это может использоваться {col} для обозначения выбранного имени столбца и {fn} для обозначения имени применяемой функции. Значение по умолчанию (NULL) эквивалентно "{col}" для случая с одной функцией и "{col}_{fn}" для случая, когда используется список для .fns .

  • Использование спецификации клея : https://github.com/tidyverse/glue


Вывод

    DELY_DATE WK_DIFF_3 WK_DIFF_4 WK_DIFF_5 WK_DIFF_6 WK_DIFF_7 WK_DIFF_8 WK_DIFF_9
1 2015-01-26        37        NA        NA        NA        NA        NA        NA
2 2015-02-02        40        40        NA        NA        NA        NA        NA
3 2015-02-09        72        72        73        NA        NA        NA        NA
4 2015-02-16        30        31        35        37        NA        NA        NA
5 2015-02-23        41        44        43        48        52        NA        NA
  WK_DIFF_10 WK_DIFF_11 WK_DIFF_12 WK_DIFF_13 WK_DIFF_14 WK_DIFF_15 WK_DIFF_16
1         NA         NA         NA         NA         NA         NA         NA
2         NA         NA         NA         NA         NA         NA         NA
3         NA         NA         NA         NA         NA         NA         NA
4         NA         NA         NA         NA         NA         NA         NA
5         NA         NA         NA         NA         NA         NA         NA
  WK_DIFF_17 WK_DIFF_18 DELY_QTY DIFF_3 DIFF_4 DIFF_5 DIFF_6 DIFF_7 DIFF_8 DIFF_9
1         NA         NA       82     45     NA     NA     NA     NA     NA     NA
2         NA         NA       62     22     22     NA     NA     NA     NA     NA
3         NA         NA       57    -15    -15    -16     NA     NA     NA     NA
4         NA         NA       57     27     26     22     20     NA     NA     NA
5         NA         NA       67     26     23     24     19     15     NA     NA
  DIFF_10 DIFF_11 DIFF_12 DIFF_13 DIFF_14 DIFF_15 DIFF_16 DIFF_17 DIFF_18
1      NA      NA      NA      NA      NA      NA      NA      NA      NA
2      NA      NA      NA      NA      NA      NA      NA      NA      NA
3      NA      NA      NA      NA      NA      NA      NA      NA      NA
4      NA      NA      NA      NA      NA      NA      NA      NA      NA
5      NA      NA      NA      NA      NA      NA      NA      NA      NA
  

Комментарии:

1. Отлично, спасибо @Darren. Кажется, мне нужно ознакомиться с этим пакетом, поскольку он намного компактнее и понятнее.

Ответ №2:

Вы могли бы попробовать что-то вроде этого:

 library(tidyverse)
df_full %>% 
  mutate(across(c(WK_DIFF_3:WK_DIFF_18),.fns = list(new = ~ .-DELY_QTY) ))
  

Вывод:

 DELY_DATE WK_DIFF_3 WK_DIFF_4 WK_DIFF_5 WK_DIFF_6 WK_DIFF_7 WK_DIFF_8 WK_DIFF_9 WK_DIFF_10 WK_DIFF_11
1 2015-01-26        37        NA        NA        NA        NA        NA        NA         NA         NA
2 2015-02-02        40        40        NA        NA        NA        NA        NA         NA         NA
3 2015-02-09        72        72        73        NA        NA        NA        NA         NA         NA
4 2015-02-16        30        31        35        37        NA        NA        NA         NA         NA
5 2015-02-23        41        44        43        48        52        NA        NA         NA         NA
  WK_DIFF_12 WK_DIFF_13 WK_DIFF_14 WK_DIFF_15 WK_DIFF_16 WK_DIFF_17 WK_DIFF_18 DELY_QTY WK_DIFF_3_new
1         NA         NA         NA         NA         NA         NA         NA       82           -45
2         NA         NA         NA         NA         NA         NA         NA       62           -22
3         NA         NA         NA         NA         NA         NA         NA       57            15
4         NA         NA         NA         NA         NA         NA         NA       57           -27
5         NA         NA         NA         NA         NA         NA         NA       67           -26
  WK_DIFF_4_new WK_DIFF_5_new WK_DIFF_6_new WK_DIFF_7_new WK_DIFF_8_new WK_DIFF_9_new WK_DIFF_10_new
1            NA            NA            NA            NA            NA            NA             NA
2           -22            NA            NA            NA            NA            NA             NA
3            15            16            NA            NA            NA            NA             NA
4           -26           -22           -20            NA            NA            NA             NA
5           -23           -24           -19           -15            NA            NA             NA
  WK_DIFF_11_new WK_DIFF_12_new WK_DIFF_13_new WK_DIFF_14_new WK_DIFF_15_new WK_DIFF_16_new WK_DIFF_17_new
1             NA             NA             NA             NA             NA             NA             NA
2             NA             NA             NA             NA             NA             NA             NA
3             NA             NA             NA             NA             NA             NA             NA
4             NA             NA             NA             NA             NA             NA             NA
5             NA             NA             NA             NA             NA             NA             NA
  WK_DIFF_18_new
1             NA
2             NA
3             NA
4             NA
5             NA
  

И если я перепутал порядок операций, то должен DELY_QTY-. извиниться.