Как извлечь определенные строки
Итак, как вы можете видеть у меня есть столбцы цена и день ниже
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