Как применить формулу по одной строке за раз в R - значения строки 2 из вычисленных значений строки 1 - PullRequest
0 голосов
/ 07 мая 2018

У меня есть фрейм данных, где мне нужно применить формулу для создания новых столбцов. Суть в том, что мне нужно вычислять эти числа по одной строке за раз. Например,

df <- data.frame(c(1:10),c(21:30),5,10)
names(df) <- c('a','b','c','d')

Теперь мне нужно создать столбцы 'c' и 'd' следующим образом. Столбец «c», значение R1 которого зафиксировано как 5. Но начиная с R2 значение «c» рассчитывается как (c (из предыдущей строки) - b (из предыдущей строки). Столбец «d» Значение R1 фиксируется как 10 , но начиная с R2, «d» рассчитывается как «c» из R2 - d из предыдущего ряда. Я хочу, чтобы мой вывод выглядел так:

A  B   C    D
1  21  5   10
2  22 -16 -26
3  23 -38 -12

И так далее. Мои фактические данные имеют более 1000 строк и 18 столбцов. Для каждой строки 5 значений столбца происходят из разных столбцов предыдущей строки (без других строк). А остальные значения столбцов рассчитываются из этих вновь рассчитанных значений строк. Я довольно затрудняюсь с созданием формулы, которая будет применять мои формулы к каждой строке, вычислять значения для этой строки и затем переходить к следующей строке. Я знаю, что немного упростил проблему, но это отражает суть того, что я пытаюсь сделать.

Это то, что я пытался:

df <- within(df, {

v1 <- shift(c)
v2 <- shift(d)
c <- v1-shift(b)
d <- c-v2
})

Однако мне нужно применять это только со строки 2 и далее, и я понятия не имею, как это сделать. Из-за этого я получаю что-то вроде этого:

a  b  c  d  v2  v1
1  21 NA NA NA  NA
2  22 4  -6 10  5
3  23 4  -6 10  5

Я получаю эти значения только несколько раз для c и d (4, -6, 10, 5).

выход

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018
df <- data.frame(a = 1:10, b = 21:30, c = 5:-4, d = 10)

for (i in (2:nrow(df))) {
  df[i, "c"] <- df[i - 1, "c"] - df[i - 1, "b"]
  df[i, "d"] <- df[i, "c"] - df[i - 1, "d"]
}

df[1:3, ]
  a  b   c   d
1 1 21   5  10
2 2 22 -16 -26
3 3 23 -38 -12

Редактировать: адаптируясь к вашему комментарию

# Let's define the coefficients of the equations into a dataframe
equation1 <- c("c", 0, 0, 0, 0, 0, -1, 1, 0) # c (from previous row) - b(from previous row)
equation2 <- c("d", 0, 0, 1, 0, 0, 0, 0, -1) # d is calculated as 'c' from R2 - d from previous row
equations <- data.frame(rbind(equation1,equation2), stringsAsFactors = F)
names(equations) <- c("y","a","b","c","d","a_previous","b_previous","c_previous","d_previous")
equations
#  y  a b c d a_previous b_previous c_previous d_previous
# "c" 0 0 0 0          0         -1          1          0
# "d" 0 0 1 0          0          0          0         -1

# define function to mutiply the rows of the dataframes 
sumProd <- function(vect1, vect2) {
  return(as.numeric(as.numeric(vect1) %*% as.numeric(vect2)))
}

# Apply the formulas to the originaldataframe
for (i in (2:nrow(df))) {
  for(e in 1:nrow(equations)) {
    df[i, equations[e, 'y']] <- sumProd(equations[e, c('a','b','c','d')], df[i, c('a','b','c','d')]) +
                                  sumProd(equations[e, paste0(c('a','b','c','d'),'_previous')], df[i - 1, c('a','b','c','d')])
  }
}
df[1:3,]
  a  b   c   d
1 1 21   5  10
2 2 22 -16 -26
3 3 23 -38 -12
0 голосов
/ 07 мая 2018

Возможно, это не самый элегантный способ сделать это с помощью цикла for, но он работает. Ваш столбец c звучит для меня как простая последовательность. Вот что я бы сделал:

df <- data.frame(c(1:10),c(21:30),5,10)
names(df) <- c('a','b','c','d')

# Use a simple sequence for c 
df$c <- seq(5,5-(dim(df)[1]-1))


# Use for loop to calculate d             

for(i in 2:(length(df$d)-1))
{
  df$d[i] <- df$c[i] - df$d[i-1]
}

> df
    a  b  c  d
1   1 21  5 10
2   2 22  4 -6
3   3 23  3  9
4   4 24  2 -7
5   5 25  1  8
6   6 26  0 -8
7   7 27 -1  7
8   8 28 -2 -9
9   9 29 -3  6
10 10 30 -4 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...