Вычесть несколько столбцов на основе условия в R

#r

#r

Вопрос:

У меня есть набор данных, который выглядит следующим образом. В моем новом наборе данных я хочу вычесть столбец (столбцы) суммы из столбца (столбцов) остатка. Например, если имеется столбец суммы 5 и столбец остатка 3, то первый столбец суммы должен быть вычтен из первого столбца остатка, 2-й со 2-м и 3-й с 3-м. Последние оставшиеся 2 столбца суммы должны быть такими, какие они есть.

 amount1  amount2   amount3   amount4  amount5     remainder1  remainder2    remainder3  
 100      250       150        250       100         80         100          100 
 200      200       350        450       100        120         100          50
 300      150       450        200       100        150         100          100
 250      550       550        100       200         50         500          200
 550      200       650        250       200        500         100          500
 

Мой новый набор данных должен выглядеть следующим образом. Пожалуйста, обратите внимание, что am означает сумму, а remостаток.

  newamount1       newamount2         newamount3      newamount4     newamount5     
 20(am1-rem1)        150(am2-rem2)      50(am3-rem3)   amount4        amount5
 80                  100                300            amount4        amount5
 150                 50                 350            amount4        amount5
 200                 50                 350            amount4        amount5
 50                  100                100            amount4        amount4
 

Ответ №1:

В базе R вы можете использовать :

 am_cols <- grep('Principal_', names(summary))

rm_cols <- grep('PrincipalPaid_', names(summary))

summary[is.na(summary)] <- 0

result <- cbind(summary[head(am_cols, length(rm_cols))] - summary[rm_cols], 
      summary[tail(am_cols, -length(rm_cols))])
names(result) <- paste0('new_principal', seq_along(result))
cbind(summary[1], result)

#  LoanId new_principal1 new_principal2 new_principal3 new_principal4
#1 825334           1965           2030           2051           2095
#2 825337           1965           2030           2051           2095
#3 838276           1961           2026           2047           2091
#4 850614              0           2275           2296           2346
#5 851791              0           2037           2059           2103
 

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

1. Я попробовал вышеупомянутое решение. Я получаю сообщение об ошибке, в котором говорится, что объект типа ‘closure’ не поддается подстановке . У меня есть столбцы в следующем формате: amount_Jan, amount_Feb и так далее. Аналогично, remainder_Jan, remainder_Feb и так далее

2. @RahulMishra Как называется ваш фрейм данных? Я использовал df , что вам нужно изменить его на основе имени вашего фрейма данных. Можете ли вы поделиться своими фактическими данными dput так же, как в моем ответе?

3. Вот мой dput structure(list(LoanId = c(825334, 825337, 838276, 850614, 851791 ), Principal_NOV20 = c(1965, 1965, 1961, 2201, 1973), Principal_DEC20 = c(2030, 2030, 2026, 2275, 2037), Principal_JAN21 = c(2051, 2051, 2047, 2296, 2059), Principal_FEB21 = c(2095, 2095, 2091, 2346, 2103 ), PrincipalPaid_NOV20 = c(NA, NA, NA, 2201, 1973), PrincipalPaid_DEC20 = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), PrincipalPaid_JAN21 = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_)), row.names = c(NA, 5L ), class = "data.frame")

4. Я использовал summary в качестве своего имени df, поэтому я заменил df на summary. Кроме того, принципал-principalpaid — это то, что я хочу как newprincipal.

5. Спасибо! Это сработало. Мне было интересно, есть ли какой-нибудь способ переименовать new_principal1 в new_principal_jan и так далее в зависимости от месяцев, так как я должен упорядочить свой набор данных по месяцам.

Ответ №2:

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

Добавьте номера строк к вашим данным. Используйте pivot_longer для перевода ваших данных в длинный формат и вычитания remainder из amount для каждого месяца / строки. Затем верните в широкий формат.

Обратите внимание, что это предполагает, что вместо цифр в конце каждого имени столбца оно заканчивается символом подчеркивания _ и сокращением месяца, согласно комментарию.

 library(tidyr)
library(dplyr)

df %>%
  mutate(rn = row_number()) %>%
  pivot_longer(cols = -rn, names_to = c(".value", "month"), names_sep = "_") %>%
  mutate(newamount = amount - remainder) %>%
  pivot_wider(id_cols = rn, names_from = month, values_from = newamount, names_prefix = "newamount_") %>%
  dplyr::select(-rn)
 

Вывод

   newamount_Jan newamount_Feb newamount_Mar newamount_Apr newamount_May
          <dbl>         <dbl>         <dbl>         <dbl>         <dbl>
1            20           150            50            NA            NA
2            80           100           300            NA            NA
3           150            50           350            NA            NA
4           200            50           350            NA            NA
5            50           100           150            NA            NA