Удалить значения из кадра данных с помощью цикла r - PullRequest
1 голос
/ 07 марта 2019

У меня следующий вопрос.Это довольно просто, но я не могу понять, где я делаю неправильно.У меня есть один год наблюдений, но проблема в том, что в конце года после 31.12.16 у меня переход на 01.01.17, а затем повторы с 2016 года.Это хорошо видно, если вы посмотрите на линии 8572-8574.Поэтому я хочу удалить эти значения (все после 2017 года с 2017 года).Моя общая база данных состоит из многих лет для анализа.Поэтому ручное удаление не вариант.

           dato horiginal hour mday mon year wday wk
8569 31.12.2016        64   20   31  11  116    6 53
8570 31.12.2016        70   21   31  11  116    6 53
8571 31.12.2016        71   22   31  11  116    6 53
8572 31.12.2016        71   23   31  11  116    6 53
8573 01.01.2017        78    0    1   0  117    0 53
8574 30.10.2016        46   12   30   9  116    0 44
8575 30.10.2016        38   13   30   9  116    0 44
8576 30.10.2016        35   14   30   9  116    0 44
8577 30.10.2016        36   15   30   9  116    0 44
8578 30.10.2016        46   12   30   9  116    0 44
8579 30.10.2016        38   13   30   9  116    0 44
'data.frame':   8629 obs. of  8 variables:
 $ dato     : chr  "01.01.2016" "01.01.2016" "01.01.2016" "01.01.2016" ...
 $ horiginal: num  76 79 78 74 75 71 74 72 71 77 ...
 $ hour     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ mday     : int  1 1 1 1 1 1 1 1 1 1 ...
 $ mon      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ year     : int  116 116 116 116 116 116 116 116 116 116 ...
 $ wday     : int  5 5 5 5 5 5 5 5 5 5 ...
 $ wk       : num  1 1 1 1 1 1 1 1 1 1 ...

Последний столбец "wk" означает неделю и является единственным увеличивающимся столбцом в этом кадре данных (начиная с 1).Мой мыслительный процесс состоит в том, чтобы сделать цикл и удалить все, если наблюдение ниже, чем предыдущие значения.

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

for (i in 1:NROW(newdf_heat$wk)) {
  total.coefs = data.frame()
  if (newdf_heat$wk[i+1]< newdf_heat$wk[i]) {
   total.coefs = newdf_heat[-c(i:nrow(newdf_heat)),]}
  }

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

Ответы [ 2 ]

3 голосов
/ 07 марта 2019

Есть ли у вас год выпуска, вы могли бы следующее:

# Extract the cumulative maximum year
my_df$max_year <- cummax(my_df$year)

# Filter those rows which are at least as big as the max_year
my_df[my_df$year >= my_df$max_year, ]

#            dato horiginal hour mday mon year wday wk max_year
# 8569 31.12.2016        64   20   31  11  116    6 53      116
# 8570 31.12.2016        70   21   31  11  116    6 53      116
# 8571 31.12.2016        71   22   31  11  116    6 53      116
# 8572 31.12.2016        71   23   31  11  116    6 53      116
# 8573 01.01.2017        78    0    1   0  117    0 53      117

Если wk постоянно увеличивается, вы также можете использовать это вместо года или извлечь год, как это сделал Ронак Шах в своем ответе.

Данные

my_df <- 
  structure(list(dato = c("31.12.2016", "31.12.2016", "31.12.2016", "31.12.2016", "01.01.2017", "30.10.2016", "30.10.2016", "30.10.2016", "30.10.2016", "30.10.2016", "30.10.2016"), 
                 horiginal = c(64L, 70L, 71L, 71L, 78L, 46L, 38L, 35L, 36L, 46L, 38L), 
                 hour = c(20L, 21L, 22L, 23L, 0L, 12L, 13L, 14L, 15L, 12L, 13L), 
                 mday = c(31L, 31L, 31L, 31L, 1L, 30L, 30L, 30L, 30L, 30L, 30L), 
                 mon = c(11L, 11L, 11L, 11L, 0L, 9L, 9L, 9L, 9L, 9L, 9L), 
                 year = c(116L, 116L, 116L, 116L, 117L, 116L, 116L, 116L, 116L, 116L, 116L), 
                 wday = c(6L, 6L, 6L, 6L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
                 wk = c(53L, 53L, 53L, 53L, 53L, 44L, 44L, 44L, 44L, 44L, 44L)), 
            class = "data.frame", row.names = c("8569", "8570", "8571", "8572", "8573", "8574", "8575", "8576", "8577", "8578", "8579"))
2 голосов
/ 07 марта 2019

Мы можем преобразовать столбец dato в Date, извлечь год, найти индекс строки, в которой «2017» встречается впервые, и удалить строки из этого индекса.

df[1:which.max(format(as.Date(df$dato, "%d.%m.%Y"), "%Y") == "2017") - 1,]

#           dato horiginal hour mday mon year wday wk
#8569 31.12.2016        64   20   31  11  116    6 53
#8570 31.12.2016        70   21   31  11  116    6 53
#8571 31.12.2016        71   22   31  11  116    6 53
#8572 31.12.2016        71   23   31  11  116    6 53

Или, если год для удаления не всегда равен «2017», а даты всегда растут, мы можем использовать diff, чтобы найти первый индекс, в котором есть падение даты, и удалить все после этого.

df[1:which.max(diff(as.Date(df$dato, "%d.%m.%Y")) < 0) - 1, ]

Также, как уже упоминалось в столбце post wk, он постоянно увеличивается, следовательно, вышеупомянутая логика diff может применяться и к столбцу wk, что избавит нас от конвертации dato в Date

df[1:which.max(diff(df$wk) < 0) - 1,]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...