R: Сгруппировать по одному столбцу и вернуть первую строку со значением больше 0 в любом из других столбцов, а затем вернуть все строки после этой строки - PullRequest
0 голосов
/ 18 сентября 2018

enter image description here

Я новичок в программировании на R и надеюсь, что кто-нибудь может помочь мне в приведенной ниже ситуации:

У меня есть кадр данных, показанный на рисунке(Исходный кадр данных), я хотел бы вернуть первую запись, сгруппированную по столбцу [ID] со значением> = 1 в любом из четырех столбцов (A, B, C или D), и все записи послестолбец [Дата] (нужный кадр данных должен выглядеть как выходной кадр данных, показанный на рисунке).В основном удалите все записи, выделенные желтым цветом.Я был бы очень признателен, если бы вы могли предоставить код R для достижения этой цели.

structure(list(ID = c(101L, 101L, 101L, 101L, 101L, 101L, 103L, 
103L, 103L, 103L), Date = c(43338L, 43306L, 43232L, 43268L, 43183L, 
43144L, 43310L, 43246L, 43264L, 43209L), A = c(0L, 0L, 0L, 0L, 
0L, 0L, 0L, 1L, 0L, 0L), B = c(0L, 2L, 0L, 0L, 0L, 0L, 0L, 1L, 
0L, 0L), C = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), D = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("ID", "Date", 
"A", "B", "C", "D"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"))

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Вот решение tidyverse.Условие filter заслуживает некоторого объяснения:

  1. сначала мы сортируем по ID и Date и group_by ID
  2. Затем для каждого идентификатора (так как мыповторно сгруппированы по ID) мы применяем условие фильтра:
    1. Проверка, для каждой строки, является ли какая-либо из переменных > 0
    2. Получить номер строки для всех строк (в группе)где это имеет место
    3. Найдите самую нижнюю (поскольку строки отсортированы по дате, это будет самое раннее)
    4. Получите значение Date для этой строки.
    5. Затем отфильтруйте строки, где Date равно >=, чем это.

Поскольку мы все еще группируем по ID, все эти вычисления будутпроисходят отдельно для каждой группы:

df %>%
    arrange(ID, Date) %>%
    group_by(ID) %>%
    filter(Date >= Date[min(which(A > 0 | B > 0 | C > 0 | D > 0))])

# A tibble: 7 x 6
# Groups:   ID [2]
     ID  Date     A     B     C     D
  <int> <int> <int> <int> <int> <int>
1   101 43232     0     0     1     0
2   101 43268     0     0     0     0
3   101 43306     0     2     0     0
4   101 43338     0     0     0     0
5   103 43246     1     1     0     0
6   103 43264     0     0     0     0
7   103 43310     0     0     0     0
0 голосов
/ 19 сентября 2018

Вот решение,

    ID       Date A B C D
1  101 26.08.2018 0 0 0 0
2  101 25.07.2018 0 2 0 0
3  101 12.05.2018 0 0 1 0
4  101 17.06.2018 0 0 0 0
5  101 24.03.2018 0 0 0 0
6  101 13.02.2018 0 0 0 0
7  103 29.07.2018 0 0 0 0
8  103 26.05.2018 1 1 0 0
9  103 13.06.2018 0 0 0 0
10 103 19.04.2018 0 0 0 0


data$Check <- rowSums(data[3:6]) 

data$Date <- as.Date(data$Date , "%d.%m.%Y")


data <- data[order(data$ID,data$Date),]


id <- unique(data$ID)

for(i in 1:length(id)) {

    data_sample <- data[data$ID == id[i],]

    data_sample <- data_sample[ min(which(data_sample$Check>0 )):nrow(data_sample),]

    if(i==1) {

        final <- data_sample


    } else {

        final <- rbind(final,data_sample)

    }

}

final <- final[,-7]

   ID       Date A B C D
3 101 2018-05-12 0 0 1 0
4 101 2018-06-17 0 0 0 0
2 101 2018-07-25 0 2 0 0
1 101 2018-08-26 0 0 0 0
8 103 2018-05-26 1 1 0 0
9 103 2018-06-13 0 0 0 0
7 103 2018-07-29 0 0 0 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...