Как извлечь определенные строки

Итак, как вы можете видеть у меня есть столбцы цена и день ниже

 Price  Day
    2   1
    5   2
    8   3
    11  4
    14  5
    17  6
    20  7
    23  8
    26  9
    29  10
    32  11
    35  12
    38  13
    41  14
    44  15
    47  16
    50  17
    53  18
    56  19
    59  20

Я тогда хочу вывод ниже

  Difference    Day
    12  5
    15  10
    15  15
    15  20

Так что теперь у меня есть разница в ценах каждые 5 дней... она просто вычитает 5-й день с первым днем ​​..... и затем 10-й день с 5-м днем ​​и т. Д..... Я уже сделал код, который разделит мои данные на 5-дневные интервалы... но я хочу код, который позволит мне минус 5-й с 1-м днем ​​.... 10-й день с 5-м днем ​​... и т. д. Таким образом, код должен выглядеть примерно так

difference<-tapply(Price[,1],Day, ____________)

Таким образом, в основном Price[,1] будут моими данными Price... тогда как "Day" - это созданная мной переменная, которая позволит мне разделить мои данные Day на 5-дневные интервалы..... Я думаю, что в пустой раздел, который я мог бы вставить в функцию или другую переменную, которая позволит мне вычесть 5-й день с ценами 1-го дня, а затем цены 10-го и 5-го дня... и т. д...... вам не нужно помогать мне разделить мои дни на интервалы... просто как сделать раздел "разница".... спасибо, ребята

3 ответа

Вот один из вариантов, если предположить, data.frame называется "SODF":

within(SODF[c(1, seq(5, nrow(SODF), 5)), ], { 
  Price <- diff(c(0, Price)) 
})[-1, ]
#    Price Day
# 5     12   5
# 10    15  10
# 15    15  15
# 20    15  20

Первый шаг - базовое подмножество. Согласно вашему описанию и ожидаемому ответу, вы хотите первую строку, а затем каждую пятую строку, начиная с строки 5:

> SODF[c(1, seq(5, nrow(SODF), 5)), ]
   Price Day
1      2   1
5     14   5
10    29  10
15    44  15
20    59  20

Оттуда вы можете использовать diff в столбце "Цена", но так как diff приведет к вектору, который на одну длину короче вашего ввода, вам нужно "дополнить" входной вектор, что я и сделал с diff(c(0, Price)),

# Correct values, but the number of rows needs to be 5
> diff(SODF[c(1, seq(5, nrow(SODF), 5)), "Price"])
[1] 12 15 15 15

Затем [-1, ] в конце просто удаляет посторонний ряд.

Обновить

В комментариях ниже @geektrader указывает в комментариях (спасибо!) Альтернативу использованию:

SODF[c(1, seq(5, nrow(SODF), 5)), ]

как ваш вклад data.frameвместо этого вы можете использовать следующее:

rbind(SODF[1,], SODF[$Day %% 5 == 0,] )

Разница в этих двух подходах заключается в том, что первый подход просто поднаборов по номеру строки, в то время как второй подход поднабора в соответствии со значением в столбце "День", извлекая строки, где "День" кратен 5. Этот второй подход может быть полезно, например, когда в наборе данных отсутствуют строки.

Ананда - это хороший подход (всегда забывай о себе). Вот еще один подход:

dat2 <- dat[seq(0, nrow(dat), by=5), ]
data.frame(Difference=diff(c(dat[1,1], dat2[, 1])), Day=dat2[, 2])

Здесь решение, если у вас есть матрица в качестве входных данных.

Последующая функция, заданная матрица mколонна col_id и числовой интервал intervвычитает каждый interv строки текущего значения в col_id столбец m матрица с предыдущим значением (5 строк перед тем же столбцом, очевидно).

Результаты сохраняются в новом столбце под названием diff и добавлен в конец m матрица.

Короче говоря, подход очень похож на используемый @Ananda Mahto.

Итак, это функция:

subtract_column <- function(m, col_id, interv) {
  select <- c(1, seq(interv, nrow(m), interv))
  cbind(m[select[-1], ], diff = diff(m[select, col_id]))
}

Пример:

# this emulates your data as a matrix
price_vect <- c(2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59)
day_vect <- 1:20
matr <- do.call(cbind, list(price = price_vect, day = day_vect))
# and this calls the function above and does the job:
# subtracts every 5 rows the current and the previous (5 rows back) value in the column `price` of matrix `matr`
subtract_column(matr, 'price', 5)

Выход:

     price day diff
[1,]    14   5   12
[2,]    29  10   15
[3,]    44  15   15
[4,]    59  20   15
Другие вопросы по тегам