Выберите строки на основе даты и другого условия в r - PullRequest
0 голосов
/ 20 июня 2020

Я хочу выбрать конкретные c клиентские сеансы на основе даты, но я не знаю, как с этим справиться. У меня есть df со всеми сеансами клиентов, и я хочу создать два новых df: один с первым сеансом каждого клиента и один со вторым сеансом каждого клиента. Какой сеанс будет первым или вторым, зависит от даты. Идентификаторы сеанса - это случайные сгенерированные числа, как и идентификаторы клиента.

Мои данные выглядят так:

Client id     Session id       Date
 8972137        95738        13-03-2019
 8972137        61718        18-03-2019
 8972137        81289        19-03-2019
 8972137        89239        20-03-2019
 56121278       91298        13-02-2019
 56121278       12794        15-02-2019
 56121278       10083        16-02-2019
 13482932       90138        03-02-2019
 13482932       23128        06-02-2019

Я хочу получить вывод для df только с первым сеансом, например:

Client id     Session id     Date
8972137        95738        13-03-2019
56121278       91298        13-02-2019
13482932       90138        03-02-2019

А для df со вторыми сессиями вроде:

Client id     Session id     Date
 8972137        61718        18-03-2019
 56121278       12794        15-02-2019
 13482932       90138        03-02-2019

Ответы [ 4 ]

1 голос
/ 20 июня 2020

Думаю, вы можете использовать эту функцию:

library (dplyr)
date_fun<-function(df, n_slice){
  result<-df %>% 
    group_by(id) %>% 
    arrange(id,Date) %>% 
    slice(n_slice)
  return (result)
}

date_fun (df, 1)

# id    session_id Date      
  <fct> <fct>      <date>    
1 1     95738      2019-03-13
2 2     91298      2019-02-13
3 3     90138      2019-02-03

date_fun (df, 2)

id    session_id Date      
  <fct> <fct>      <date>    
1 1     61718      2019-03-18
2 2     12794      2019-02-15
3 3     23128      2019-02-06

n_slice - номер сеанса

1 голос
/ 20 июня 2020

A baseR подход,

index <- order(mydata[,1])[!duplicated(sort(mydata[,1]))] # Finds first occurance

mydata[index,]

дает,

  Clientid Sessionid       Date
1        1     95738 13-03-2019
5        2     91298 13-02-2019
8        3     90138 03-02-2019


mydata[(index+1),]

дает,

  Clientid Sessionid       Date
2        1     61718 18-03-2019
6        2     12794 15-02-2019
9        3     23128 06-02-2019

Данные:

mydata <- read.table(text="Clientid     Sessionid     Date
    1             95738        13-03-2019
    1             61718        18-03-2019
    1             81289        19-03-2019
    1             89239        20-03-2019
    2             91298        13-02-2019
    2             12794        15-02-2019
    2             10083        16-02-2019
    3             90138        03-02-2019
    3             23128        06-02-2019",header=T)
0 голосов
/ 20 июня 2020

Вот один из подходов на основе R:

#Convert to date
df$Date <- as.Date(df$Date, '%d-%m-%Y')
#Order the dataframe based on Clientid and date
df <- df[with(df, order(Clientid, Date)),]
#Assign session number for each Clientid
df$Session_No <- with(df, ave(Sessionid, Clientid, FUN = seq_along))

Теперь вы можете subset данные для любых данных сеанса, которые вам нужны:

subset(df, Session_No == 1)

#  Clientid Sessionid       Date Session_No
#1  8972137     95738 2019-03-13          1
#8 13482932     90138 2019-02-03          1
#5 56121278     91298 2019-02-13          1

subset(df, Session_No == 2)

#  Clientid Sessionid       Date Session_No
#2  8972137     61718 2019-03-18          2
#9 13482932     23128 2019-02-06          2
#6 56121278     12794 2019-02-15          2

данные

df <- structure(list(Clientid = c(8972137L, 8972137L, 8972137L, 8972137L, 
56121278L, 56121278L, 56121278L, 13482932L, 13482932L), Sessionid = c(95738L, 
61718L, 81289L, 89239L, 91298L, 12794L, 10083L, 90138L, 23128L
), Date = c("13-03-2019", "18-03-2019", "19-03-2019", "20-03-2019", 
"13-02-2019", "15-02-2019", "16-02-2019", "03-02-2019", "06-02-2019"
)), class = "data.frame", row.names = c(NA, -9L))
0 голосов
/ 20 июня 2020

Это берет каждую i -ю строку идентификаторов и перечисляет их в фреймы данных.

res <- lapply(unique(dat$Client.id), function(i) 
  do.call(rbind, by(dat, dat$Client.id, function(x) x[i, ])))
res
# [[1]]
#   Client.id Session.id       Date
# 1         1      95738 13-03-2019
# 2         2      91298 13-02-2019
# 3         3      90138 03-02-2019
# 
# [[2]]
#   Client.id Session.id       Date
# 1         1      61718 18-03-2019
# 2         2      12794 15-02-2019
# 3         3      23128 06-02-2019
# 
# [[3]]
#   Client.id Session.id       Date
# 1         1      81289 19-03-2019
# 2         2      10083 16-02-2019
# 3        NA         NA       <NA>

Изменить: Чтобы «распаковать» перечисленные фреймы данных, используйте list2env после, используйте setNames, чтобы дать желаемые имена.

list2env(setNames(res, paste0("dat", 1:length(res))), envir=.GlobalEnv)
ls()
# [1] "dat"  "dat1" "dat2" "dat3" "res" 

Данные:

dat <- structure(list(Client.id = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 
3L), Session.id = c(95738L, 61718L, 81289L, 89239L, 91298L, 12794L, 
10083L, 90138L, 23128L), Date = c("13-03-2019", "18-03-2019", 
"19-03-2019", "20-03-2019", "13-02-2019", "15-02-2019", "16-02-2019", 
"03-02-2019", "06-02-2019")), class = "data.frame", row.names = c(NA, 
-9L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...