Вычисление с участием взаимозависимых столбцов во фрейме данных

#r #dataframe

#r #фрейм данных

Вопрос:

 Data <- data.frame(
  A = rnorm(1:10),
  B = rnorm(1:10),
  C = rnorm(1:10),
  D = rnorm(1:10),
  X = sample(c(1,0), size=10, replace = TRUE)
)
  

Во фрейме данных мне нужно создать два столбца Y и Z, где

Первое наблюдение за Y будет равно константе, скажем, 10

Второе и последующие наблюдения Y, т. е. от строки 2 до 10, в этом случае будут равны = 10 Z [предыдущее наблюдение]

пример

 if Z[1] = 10 then Y[2] = 10   Z[1] = 20

if Z[2] = 20 then Y[3] = 10   Z[2] = 30

if Z[3] = 50 then Y[4] = 10   Z[3] = 60
  

и так далее до длины Data фрейма данных.


Теперь, что касается Z, оно вычисляется следующим образом:

 First observation of Z is IF(X1>0,0,Y1-SUM(A1 B1 C1 D1))
Second observation of Z is IF(X2>0,0,Y2-SUM(A2 B2 C2 D2))
Third observation of Z is IF(X3>0,0,Y3-SUM(A3 B3 C3 D3))
  

то есть проверяется, равно ли X наблюдению из той же строки > 0, тогда Z для этой строки равно 0, в противном случае это Y1 — sum (A: D) для той же строки

и так далее до длины фрейма данных.

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

1. Итак, для вычисления Z вам нужно Y и для вычисления Y нам нужно Z ?

2. Да, но только для предыдущих строк. Значение для Y(n 1) вам понадобится Z(n) , а для вычисления Z(n) вам понадобится Y(n) где n = количество наблюдений с 1-м наблюдением Y(1) = constant .

3. Некоторые моменты: 1) Всегда используйте set.seed при генерации случайных данных (при использовании sample , rnorm и т.д.). 2) Для вычисления Y первое значение фиксируется равным 10, но второе значение и далее вычисление должно быть Y[3] = Y[2] Z[2] , а не Y[3] = 10 Z[2] потому что 10 равно Y[1] . По крайней мере, так написано на скриншоте.

4. @RonakShah Я сожалею о скриншоте. Я сгенерировал это в Excel и забыл исправить ссылку в столбце Y строка 2

5. ооо … тогда Y значение должно вычисляться всегда Y[1] предыдущая Z строка? Итак, для Y[3] это было бы Y[3] = Y[1] Z[2] и для Y[4] , Y[4] = Y[1] Z[3] ?

Ответ №1:

Поскольку существует взаимозависимость в каждой строке в предыдущей строке, здесь используется for цикл

 Data$Y <- 10
Data$Z <- 0

for (i in seq_len(nrow(Data))) {
   if(i > 1)
    Data$Y[i] <- Data$Y[1]   Data$Z[i-1]

   if(Data$X[i] > 0) 
      Data$Z[i] <- 0 
   else
      Data$Z[i] <- with(Data, Y[i] - (A[i] B[i] C[i] D[i]))
}

Data
#            A           B          C          D X        Y         Z
#1   0.6607697  0.05785971  0.2053518 -0.3366816 0 10.00000  9.412700
#2  -2.0529830  1.10397550  1.0162833 -0.6592560 0 19.41270 20.004681
#3  -1.4992061 -0.02561697  0.4089990 -0.1007670 1 30.00468  0.000000
#4   1.4712331  0.51484639 -0.7052355  0.7039078 0 10.00000  8.015248
#5   1.4591385  0.99005668  0.2356143  0.4380549 0 18.01525 14.892384
#6   0.1401390  0.30345432  0.3451300  1.4971479 0 24.89238 22.606512
#7   0.2091844 -0.93007223 -1.0197996  0.2162444 1 32.60651  0.000000
#8  -3.0360898  0.08403068 -1.4118223 -1.4953378 0 10.00000 15.859219
#9  -0.4869341  0.52677963 -1.3638423  0.1249940 1 25.85922  0.000000
#10 -1.0878673  0.01586862  0.8731049 -1.0380945 0 10.00000 11.236988
  

данные

 set.seed(234)
Data <- data.frame(
   A = rnorm(1:10),
   B = rnorm(1:10),
   C = rnorm(1:10),
   D = rnorm(1:10),
   X = sample(c(1,0), size=10, replace = TRUE)
)
  

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

1. Я не уверен, почему, но в вашем коде это Data$Z[i] <- with(Data, Y[i]- A[i] B[i] C[i] D[i]) и Data$Z[i] <- with(Data, Y[i]- (A[i] B[i] C[i] D[i])) дает другой результат. и второй дает правильный ответ для меня.

2. да, я проверял то же самое, что вы правы, потому что 1 - (2 3) отличается от 1 - 2 3 . Какой я глупый.