Применять задержку или опережать в порядке возрастания для кадра данных

df1 <- read.csv("C:/Users/uni/DS-project/df1.csv")
df1

    year value
1  2000     1
2  2001     2
3  2002     3
4  2003     4
5  2004     5
6  2000     1
7  2001     2
8  2002     3
9  2003     4
10 2004     5
11 2000     1
12 2001     2
13 2002     3
14 2003     4
15 2004     5
16 2000     1
17 2001     2
18 2002     3
19 2003     4
20 2004     5

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

у нас есть набор из 5 наблюдений за каждый год, повторяемый n раз, в выходных данных за 1-й год нам нужно удалить 2000 и его соответствующее значение, аналогично для второго года, которым мы пренебрегаем 2000 и 2001 и его соответствующим значением, и для 3-го года удалить - 2000, 2001, 2002 и его значение. И так далее.

так что мы можем получить ниже вывод в нижеуказанном порядке.

output: 
year    value
2000    1
2001    2
2002    3
2003    4
2004    5
2001    2
2002    3
2003    4
2004    5
2002    3
2003    4
2004    5
2003    4
2004    5

пожалуйста помоги.

5 ответов

Просто для удовольствия, добавление векторизованного решения с использованием поднабора матрицы

m <- matrix(rep(TRUE, nrow(df)), 5)
m[upper.tri(m)] <- FALSE
df[m,]
#    year value
# 1  2000     1
# 2  2001     2
# 3  2002     3
# 4  2003     4
# 5  2004     5
# 7  2001     2
# 8  2002     3
# 9  2003     4
# 10 2004     5
# 13 2002     3
# 14 2003     4
# 15 2004     5
# 19 2003     4
# 20 2004     5
library(dplyr)

df %>% 
  group_by(g = cumsum(year == 2000)) %>% 
  filter(row_number() >= g) %>% 
  ungroup %>% 
  select(-g)


# # A tibble: 14 x 2
#     year value
#    <int> <int>
#  1  2000     1
#  2  2001     2
#  3  2002     3
#  4  2003     4
#  5  2004     5
#  6  2001     2
#  7  2002     3
#  8  2003     4
#  9  2004     5
# 10  2002     3
# 11  2003     4
# 12  2004     5
# 13  2003     4
# 14  2004     5

Ниже grp 1 для каждой строки первой группы, 2 для второй и т. д. Seq равно 1, 2, 3, ... для последовательных рядов каждой группы. Теперь просто выберите те строки, для которых Seq по крайней мере такой же большой, как grp, Это приводит к удалению первых i-1 строк из i-й группы для i = 1, 2, ... .

grp <- cumsum(df1$year == 2000)
Seq <- ave(grp, grp, FUN = seq_along)
subset(df1, Seq >= grp)

Мы могли бы поочередно написать это в менее общей форме:

subset(df1, 1:5 >= rep(1:4, each = 5))

В любом случае результат любого оператора подмножества:

   year value
1  2000     1
2  2001     2
3  2002     3
4  2003     4
5  2004     5
7  2001     2
8  2002     3
9  2003     4
10 2004     5
13 2002     3
14 2003     4
15 2004     5
19 2003     4
20 2004     5

С помощью sequence:

df[5-rev(sequence(2:5)-1),]
#     year value
# 1   2000     1
# 2   2001     2
# 3   2002     3
# 4   2003     4
# 5   2004     5
# 2.1 2001     2
# 3.1 2002     3
# 4.1 2003     4
# 5.1 2004     5
# 3.2 2002     3
# 4.2 2003     4
# 5.2 2004     5
# 4.3 2003     4
# 5.3 2004     5

как это устроено:

5-rev(sequence(2:5)-1)
# [1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5
rev(sequence(2:5)-1)
# [1] 4 3 2 1 0 3 2 1 0 2 1 0 1 0
sequence(2:5)-1
# [1] 0 1 0 1 2 0 1 2 3 0 1 2 3 4
sequence(2:5)
# [1] 1 2 1 2 3 1 2 3 4 1 2 3 4 5

С помощью lapply():

to <- nrow(df) / 5 - 1
df[-unlist(lapply(1:to, function(x) seq(1:x) + 5*x)), ]
   year value
1  2000     1
2  2001     2
3  2002     3
4  2003     4
5  2004     5
7  2001     2
8  2002     3
9  2003     4
10 2004     5
13 2002     3
14 2003     4
15 2004     5
19 2003     4
20 2004     5

куда unlist(lapply(1:to, function(x) seq(1:x) + 5*x)) индексы для пропуска:

[1]  6 11 12 16 17 18
Другие вопросы по тегам