在每天中查找值的第一个出现

4

我有一个数据框,其中包含日期时间和值(介于0和1之间),我想找到每天第一次出现值为1的事件

df <- read.table(header = TRUE, text = '
Datetime                   Value
"2016-12-01 23:45:00"      0
"2016-12-01 23:50:00"      1
"2016-12-02 00:05:00"      1
"2016-12-02 00:10:00"      0
"2016-12-03 04:10:00"      0
"2016-12-03 04:15:00"      0
"2016-12-04 12:10:00"      1
"2016-12-04 12:15:00"      1
')
df$Datetime <- as.POSIXct(df$Datetime, "%Y-%m-%d %H:%M:%S", tz="UTC")
View(df)

What i would like to have is:

2016-12-01 23:50:00      1
2016-12-02 00:05:00      1
2016-12-04 12:10:00      1

我尝试使用match()和aggregate()解决问题,但目前没有成功。此外,我能够用for循环解决问题,但是a)速度非常慢,b)可能不是正确的方法。

4个回答

5
一个使用 dplyr 的替代方案:
library(dplyr)
df %>%
 #group
 group_by(as.Date(Datetime)) %>%
 #select only those where value equals 1
 filter(Value == 1) %>%
 #get only the first row
 slice(1) %>%
 #ungroup
 ungroup %>%
 #select columns
 select(Datetime, Value)

输出:

# A tibble: 3 x 2
             Datetime Value
               <time> <int>
1 2016-12-01 23:50:00     1
2 2016-12-02 00:05:00     1
3 2016-12-04 12:10:00     1

根据@Akrun的评论,或者说:
df %>% 
  group_by(Date = as.Date(Datetime)) %>% 
  slice(which(Value==1)[1])

1
我认为可以通过df %>% group_by(Date = as.Date(Datetime)) %>% slice(which(Value==1)[1])来减少一步。 - akrun
1
非常感谢@akrun。太棒了! - LyzandeR

4
我们可以将所有 Value==1 的行分离出来。当然,第一个这样的行应该被包括在内。在第一个行之后,只有当该行的日期与前一个 Value==1 行的日期不同时,才会包括该行。
Ones = df[df$Value == 1,]
DayChange = c(1, which(diff(as.Date(Ones$Datetime)) > 0)+1)
Ones[DayChange,]
             Datetime Value
2 2016-12-01 23:50:00     1
3 2016-12-02 00:05:00     1
7 2016-12-04 12:10:00     1

3

这里有一个使用data.table的选项。将'data.frame'转换为'data.table'(setDT(df)),按照将'Datetime'转换为Date进行分组,并将'i'指定为Value==1,我们可以获得第一个出现1的索引(.I[1]),然后使用它来筛选行。

library(data.table)
setDT(df)[df[Value==1, .I[1], .(as.Date(Datetime))]$V1]
#              Datetime Value
#1: 2016-12-01 23:50:00     1
#2: 2016-12-02 00:05:00     1
#3: 2016-12-04 12:10:00     1

2
df[!duplicated(paste0(as.Date(df$Datetime), df$Value)) & df$Value == 1, ]
#              Datetime Value
# 2 2016-12-01 23:50:00     1
# 3 2016-12-02 00:05:00     1
# 7 2016-12-04 12:10:00     1

解释:

创建日期(as.Date)- 使用paste0创建值组合。创建一个逻辑向量,指示哪些组合不是前面元素的重复项(!duplicated),并将其与“Value”为1的测试组合(& df $ Value == 1 )。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接