Сопоставить строку и столбец, затем вычесть значение - PullRequest
0 голосов
/ 08 октября 2019

Я согласовываю два набора данных. A имеет список транзакций и значение. B содержит несколько значений после процесса. Я хочу вычесть значения в A из идентифицированного поля в B.

library(tidyverse)
A<-tribble(
  ~idA, ~group, ~column, ~value, ~idB,
  1, "x", "t1", 11, 1,
  2, "x", "t1",  22, 3,
  3, "x", "t3",  33, 4,
  4, "x", "t1",  25, 5)

B<-tribble(
  ~idB, ~group, ~t1, ~t2, ~t3,
  1, "x", 11, 0, 0,
  2, "x", 0, 11, 0,
  3, "x", 22, 0, 0 ,
  4, "x", 0, 0, 33,
  5, "x", 50, 50, 50)

Желаемый результат:

Boutput<-tribble(
  ~idB, ~g,~t1, ~t2, ~t3,
  1, "x", 0, 0, 0, 
  2, "x", 0, 11, 0, 
  3, "x", 0, 0, 0,  
  4, "x", 0, 0, 0,  
  5, "x", 25, 50, 50)

Я пробовал inner_joining, затем мутировал на основеправила.

Как математически вычесть спички?

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Я не решался опубликовать это, но подумал, что это может быть полезно при поиске некоторых альтернативных решений.

Я мог бы рассмотреть преобразование A из длинного в широкое сначала:

Awide <- A %>%
  pivot_wider(names_from = column)

R> Awide
# A tibble: 4 x 5
    idA group   idB    t1    t3
  <dbl> <chr> <dbl> <dbl> <dbl>
1     1 x         1    11    NA
2     2 x         3    22    NA
3     3 x         4    NA    33
4     4 x         5    25    NA

В этом случае нет значений для t2. Прежде чем объединить A и B, убедитесь, что есть столбцы для всех 3 (t1, t2, t3):

cols <- c("idA", "group", "idB", "t1", "t2", "t3")
missing <- setdiff(cols, names(Awide))
Awide[missing] <- NA
Awide <- Awide[cols]

R> Awide
# A tibble: 4 x 6
    idA group   idB    t1 t2       t3
  <dbl> <chr> <dbl> <dbl> <lgl> <dbl>
1     1 x         1    11 NA       NA
2     2 x         3    22 NA       NA
3     3 x         4    NA NA       33
4     4 x         5    25 NA       NA

Затем можно сделать left_join иубедитесь, что все присутствующие NAs равны нулю для последующего вычитания.

AB <- left_join(B, Awide, by=c("idB", "group")) %>%
  mutate_at(c("t1.y", "t2.y", "t3.y"), ~replace(., is.na(.), 0))

R> AB
# A tibble: 5 x 9
    idB group  t1.x  t2.x  t3.x   idA  t1.y  t2.y  t3.y
  <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1 x        11     0     0     1    11     0     0
2     2 x         0    11     0    NA     0     0     0
3     3 x        22     0     0     2    22     0     0
4     4 x         0     0    33     3     0     0    33
5     5 x        50    50    50     4    25     0     0

Затем будет выполнено вычитание для столбцов, соответствующих шаблону t*.x и t*.y (альтернативы могут использоваться в зависимости от того, чтовам нужно):

tdiff <- AB[,grepl("^t.*\\.x$", names(AB))] - AB[,grepl("^t.*\\.y$", names(AB))]

R> tdiff
  t1.x t2.x t3.x
1    0    0    0
2    0   11    0
3    0    0    0
4    0    0    0
5   25   50   50

Затем свяжите эти итоги с AB, чтобы получить окончательный результат:

cbind(AB[,1:2,drop=FALSE], tdiff)

  idB group t1.x t2.x t3.x
1   1     x    0    0    0
2   2     x    0   11    0
3   3     x    0    0    0
4   4     x    0    0    0
5   5     x   25   50   50
0 голосов
/ 09 октября 2019

Это цикл, который я придумал

Bout<-B
for (i in A$idA){
  Bout[A$idB[i],A$column[i]] <- (as.numeric(Bout[A$idB[i],A$column[i]])) - A$value[i]
}
Bout
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...