每组的第一个和最后一个值的子集

时间:2015-08-05 13:05:38

标签: r dataframe

我在R中有一个数据框,其中有两列 temp timeStamp 。数据定期具有 temp 值。数据帧的一部分看起来像 -

enter image description here

我必须创建显示温度随时间变化的折线图。从这里可以看出, timeStamp temp 值保持不变。拥有这些重复值会增加数据文件的大小,我想删除它们。所以输出应该是这样的 -

enter image description here

仅显示有变化的值。 想不出一种方法可以在R中完成这个想法。任何正确方向的输入都会非常有用。

2 个答案:

答案 0 :(得分:1)

一种选择是使用data.table。我们转换了' data.frame'到' data.table' (setDT(df1))。通过“临时”分组,我们对每个组的第一个和最后一个观察(.SD[c(1L, .N)])进行了分组。如果每个组只有一个值,我们就这样行(else .SD)。

library(data.table)
setDT(df1)[, if(.N>1) .SD[c(1L, .N)] else .SD, by =temp]
#    temp val
#1: 22.50   1
#2: 22.50   4
#3: 22.37   5
#4: 22.42   6
#5: 22.42   7

base R选项duplicated。我们检查了“{< temp”中的duplicated值。 (输出是逻辑矢量),并检查反面的复制(fromLast=TRUE)。使用&查找两种情况下TRUE的元素,否定(!)并对' df1'的行进行分组。

df1[!(duplicated(df1$temp) & duplicated(df1$temp,fromLast=TRUE)),]
#   temp val
#1 22.50   1
#4 22.50   4
#5 22.37   5
#6 22.42   6
#7 22.42   7

数据

df1 <- data.frame(temp=c(22.5, 22.5, 22.5, 22.5, 22.37,22.42, 22.42), val=1:7)

答案 1 :(得分:1)

这是一个dplyr解决方案:

# Toy data
df <- data.frame(time = seq(20), temp = c(rep(60, 5), rep(61, 7), rep(59, 3), rep(60, 5)))

# Now filter for the first and last rows and ones bracketing a temperature change
df %>% filter(temp!=lag(temp) | temp!=lead(temp) | time==min(time) | time==max(time))

  time temp
1    1   60
2    5   60
3    6   61
4   12   61
5   13   59
6   15   59
7   16   60
8   20   60

如果数据按第三列(id)分组,只需在过滤步骤之前添加group_by(id) %>%