【发布时间】:2015-08-05 13:05:38
【问题描述】:
我在 R 中有一个包含两列 temp 和 timeStamp 的数据框。数据定期具有 temp 值。数据框的一部分看起来像 -
我必须创建显示温度随时间变化的折线图。从这里可以看出,temp 值在多个timeStamp 中保持不变。拥有这些重复值会增加数据文件的大小,我想删除它们。所以输出应该是这样的-
仅显示发生变化的值。 想不出在 R 中完成这种想法的方法。任何正确方向的输入都会非常有帮助。
【问题讨论】:
我在 R 中有一个包含两列 temp 和 timeStamp 的数据框。数据定期具有 temp 值。数据框的一部分看起来像 -
我必须创建显示温度随时间变化的折线图。从这里可以看出,temp 值在多个timeStamp 中保持不变。拥有这些重复值会增加数据文件的大小,我想删除它们。所以输出应该是这样的-
仅显示发生变化的值。 想不出在 R 中完成这种想法的方法。任何正确方向的输入都会非常有帮助。
【问题讨论】:
这是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) %>%即可。
【讨论】:
一个选项是使用data.table。我们将“data.frame”转换为“data.table”(setDT(df1))。按“temp”分组,我们对每组的第一个和最后一个观察值 (.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)
【讨论】: