Вычитание значения из значения выше при определенных условиях - без цикла - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь получить значение баланса от df, который выглядит следующим образом

df1

Name   Year    Ch1    Origin
A      1995    x1      a
A      1996    x2      b
A      1997    x3      a
A      2000    x4      a
B      1997    y1      c
B      1998    y2      c

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

Name   Year   Ch1    Bil
A      1995    x1    
A      1996    x2    %
A      1997    x3    %
A      2000    x4    %
B      1997    y1  
B      1998    y2    %

Я хочу, чтобы "Bil" был - X2 / X1 (значение предыдущего года, деленное на последний год) ЕСЛИ X2> X1 - -X1 / X2 ЕСЛИ X1

for (i in nrow(df1))
  if (df[i,1]==df[i-1,1]) {
      if (df[i,3]>df[i-1,3] {
          df$Bil<-(df[i,3]/df[i-1,3])
      } else df$Bil<-(-df[i-1,3]/df[i,3])
  } 

Есть ли более элегантный или более быстрый способ рассчитать это? Таким образом, мне действительно нужно убедиться, что набор данных находится в правильном порядке (начиная с более старых до последних лет). Допустим, также зависит от дополнительных деталей, таких как происхождение, так что вычисление происходит только в том случае, если имя и происхождение совпадают?

1 Ответ

2 голосов
/ 18 февраля 2020

Вот базовый код R, который применяется ave + pmax. Надеюсь, что приведенный ниже код может достичь вашей цели

df <- within(df,Bill <- ave(Ch1,Name,FUN = function(v) c(NA,sign(v[-1]-v[-length(v)])*pmax(v[-1]/v[-length(v)],v[-length(v)]/v[-1]))))

, чтобы

> df
  Name Year Ch1 Origin      Bill
1    A 1995  11      a        NA
2    A 1996  12      b  1.090909
3    A 1997   3      a -4.000000
4    A 2000  14      a  4.666667
5    B 1997  21      c        NA
6    B 1998  12      c -1.750000

DATA

df <- structure(list(Name = c("A", "A", "A", "A", "B", "B"), Year = c(1995L, 
1996L, 1997L, 2000L, 1997L, 1998L), Ch1 = c(11L, 12L, 3L, 14L, 
21L, 12L), Origin = c("a", "b", "a", "a", "c", "c")), class = "data.frame", row.names = c(NA, 
-6L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...