创建一个新列,在两列中添加天数,其中一列包含数据,另一列包含ID

时间:2019-06-24 18:51:48

标签: r date split each days

我有一个data.frame loc_teste2,其列为:Ptt(我有36种不同的Ptt)和Date,如下所示:

Ptt      Date   
88734    05:39:18 23-Oct-2016  
88734    06:53:13 23-Oct-2016
88734    08:32:18 24-Oct-2016
88734    06:45:27 19-Dez-2016
88734    12:30:43 20-Dez-2016
129041   02:45:35 18-Nov-2016
129041   04:55:24 19-Nov-2016
129041   06:45:30 19-Nov-2016
129041   07:10:32 20-Nov-2016
129041   03:43:54 10-Jan-2017
120941   14:54:39 11-Jan-2017
...

因此,我将列Date拆分为另一列Days

loc_teste2$Date<- as.character(loc_teste2$Date)

loc_teste2$Days <- sapply(strsplit(loc_teste2$Date, split=' ', fixed=TRUE), function(x) (x[2]))

loc_teste2$Days <- as.POSIXct(loc_teste2$Days, format = "%d-%b-%Y",tz = "GMT",usetz = TRUE)

loc_teste2$Date <- as.POSIXct(loc_teste2$Date, format = "%H:%M:%S %d-%b-%Y",tz = "GMT",usetz = TRUE)

返回:

Ptt      Date                       Days
88734    2016-10-23 05:39:18    2016-10-23
88734    2016-10-23 06:53:13    2016-10-23     
88734    2016-10-23 08:32:18    2016-10-24 
88734    2016-12-19 06:45:27    2016-12-19
88734    2016-12-20 12:30:43    2016-12-20
129041   2016-10-23 02:45:35    2016-10-18 
129041   2016-10-23 04:55:24    2016-11-19 
129041   2016-10-23 06:45:30    2016-11-19 
129041   2016-10-23 07:10:32    2016-11-20 
129041   2017-01-10 03:43:54    2017-01-10
120941   2017-01-11 14:54:39    2017-01-11
...

然后,我想创建一个新列Mig,该列在第一天为Ptt列中的每个Days添加40天,其中: 如果日期距离Ptt的第一天起最多40天,则返回1 如果日期是从Ptt的第一个日期算起的40天之后,它将返回2,如下所示:

Ptt      Date                       Days        Mig
88734    2016-10-23 05:39:18    2016-10-23     1  #based in this date (the first date for this Ptt)
88734    2016-10-23 06:53:13    2016-10-23     1
88734    2016-10-23 08:32:18    2016-10-24     1 
88734    2016-12-19 06:45:27    2016-12-19     2
88734    2016-12-20 12:30:43    2016-12-20     2
129041   2016-10-23 02:45:35    2016-10-18     1  #based in this date (the first date for this Ptt)
129041   2016-10-23 04:55:24    2016-11-19     1 
129041   2016-10-23 06:45:30    2016-11-19     1 
129041   2016-10-23 07:10:32    2016-11-20     1 
129041   2017-01-10 03:43:54    2017-01-10     2
120941   2017-01-11 14:54:39    2017-01-11     2
...

每个人都有一个想法怎么做?

Ps:最好用日期+ 40天创建一列Mig,然后用1或2创建另一列Mig2

1 个答案:

答案 0 :(得分:0)

如果使用tidyverse和lubridate软件包,则可以利用group_by函数并更轻松地操作日期。下面的代码具有一些中间步骤来重现部分数据,但是您可以只使用“ group_by”之后的块。它会返回true或false而不是一两个,但是如果需要,您可以使用ifelse()函数编辑代码。

library(lubridate)
df <- read.delim(text = "Ptt      Date   
88734    05:39:18 23-Oct-2016  
88734    06:53:13 23-Oct-2016
88734    08:32:18 24-Oct-2016
88734    06:45:27 19-Dez-2016
88734    12:30:43 20-Dez-2016
129041   02:45:35 18-Nov-2016
129041   04:55:24 19-Nov-2016
129041   06:45:30 19-Nov-2016
129041   07:10:32 20-Nov-2016
129041   03:43:54 10-Jan-2017
120941   14:54:39 11-Jan-2017", sep = "\t")

df %>% 
  separate("Ptt......Date", into = c("ptt", "time", "date"), sep = "\\s+") %>% 
  mutate(date = str_replace(date, pattern = "Dez", replacement = "Dec"), date2 = dmy(date)) %>% 
  group_by(ptt) %>% 
  mutate(threshold = min(date2)+days(40), past_threshold = date2 > threshold)

从只有Ptt和Date的第一个数据帧开始。也许在使用lubridate和tidyverse的情况下尝试以下方法。

library(tidyverse)
library(lubridate)
loc_teste2 %>% 
  mutate(Ptt = as.character(Ptt), Date = as.character(Date), Date = str_replace(Date, pattern = "Dez", replacement = "Dec"), Date = parse_date_time(Date, order = "hmsdmy")) %>% 
  group_by(Ptt) %>% 
  mutate(Threshold = min(Date) + days(40)) %>% 
  ungroup() %>% 
  mutate(Past_Threshold = Date > Threshold)

enter image description here