我有一个带有日期时间和值(在0和1之间)的data.frame,我想找到第一次出现的值= 1 每天。< / p>
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)
我想拥有的是:
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)可能不是它的意思。
答案 0 :(得分:4)
我们可以使用Value==1
分隔所有行。当然,应该包括其中的第一个。在第一个之后,只有当日不等于前一行的值== 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
答案 1 :(得分:3)
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])
答案 2 :(得分: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
) 。
答案 3 :(得分:1)
以下是使用data.table
的选项。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)
),按转换日期&#39;分组到Date
,指定&#39; i&#39;作为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