我不擅长“R”并且不确定如何重新排列和子集时间序列数据。对不起,如果这个问题听起来很愚蠢。 我有一个海潮的时间序列数据,每天有四个值(也有缺失值)。涨潮的两个值和退潮的两个值。时间和日期在同一列中给出,但在不同的行中。现在,我想仅将白天(从早上7点到晚上7点)的数据分组,而不是晚上。然后我想将数据排列在三列中i)日期,ii)时间和iii)潮汐。对于Tide,我只需要最小值和最大值。以下是数据和所需数据排列的示例。对于每个日期,数据排列在三行中,类似于示例。
1/1/2011 Low High Low NA
Time 2:58 AM 9:38 AM 5:19 PM NA
Tide 1.2 m 2.2 m 0.6 m NA
1/2/2011 High Low High Low
Time 2:07 AM 4:22 AM 10:19 AM 6:07 PM
Tide 1.4 m 1.3 m 2.3 m 0.4 m
Date Time Tide
1/1/2011 17:19 0.6
1/1/2011 9:38 2.2
1/2/2011 2:07 1.4
1/2/2011 18:07 0.4
答案 0 :(得分:1)
输入DF
假设如下面的注释中所示。
g
,分组向量,每行DF
有一个元素,等于c(1, 1, 1, 2, 2, 2, ...)
。计算g
的替代方法是n <- nrow(DF); g <- gl(n, 3, n)
或n <- nrow(DF); g <- rep(1:3, n, n)
。
然后,我们使用by
将DF
拆分为组,并将指定的匿名函数应用于g
定义的每个组。
匿名函数结合当前组中的日期和时间来创建日期/时间dt
,利用共同日期为x[1,1]
的事实和清理之前的时间在x[2,-1]
。
使用dt
和x[2, -1]
中的潮汐(在清理之前),它会计算三列中的每一列,并将它们排列到数据框中。然后有一个注释掉的行,删除NA值。如果你想要这个取消注释它。将到目前为止获得的数据帧子集到上午7点到下午7点,并进一步取两行,包括最小和最大潮。我们按时间排序。
最后do.call("rbind", ...)
将这些组放在一个整体数据框中。
没有使用任何包裹。
g <- cumsum(grepl("\\d", DF$V1))
Long <- do.call("rbind", by(DF, g, function(x) {
dt <- as.POSIXct(paste(x[1,1], as.matrix(x[2, -1])), format = "%m/%d/%Y %I:%M %p")
X <- data.frame(Date = as.Date(dt),
Time = format(dt, "%H:%M"),
Tide = as.numeric(sub("m", "", as.matrix(x[3, -1]))),
stringsAsFactors = FALSE)
# X <- na.omit(X)
X <- subset(X, Time >= "07:00" & Time <= "19:00")
X <- X[c(which.min(X$Tide), which.max(X$Tide)), ]
X[order(X$Time), ]
}))
给出以下内容 - 请注意,问题输出中的第三行不是在早上7点到晚上7点之间,因此这里的输出必然不同。
> Long
Date Time Tide
1.2 2011-01-01 09:38 2.2
1.3 2011-01-01 17:19 0.6
2.3 2011-01-02 10:19 2.3
2.4 2011-01-02 18:07 0.4
注意:以可重现的形式假设输入DF
如下:
Lines <- "1/1/2011,Low,High,Low,NA
Time,2:58 AM,9:38 AM,5:19 PM,NA
Tide,1.2 m,2.2 m,0.6 m,NA
1/2/2011,High,Low,High,Low
Time,2:07 AM,4:22 AM,10:19 AM,6:07 PM
Tide,1.4 m,1.3 m,2.3 m,0.4 m"
DF <- read.table(text = Lines, sep = ",", as.is = TRUE)
答案 1 :(得分:0)
如果列表不是太长,那么只需通过映射单元格和过滤,就可以更容易地在电子表格中完成这项工作。但是在R中使用zoo和tidyverse的一种方法是:
假设原始数据帧的列名为C1:C5
C1 C2 C3 C4 C5
<chr> <chr> <chr> <chr> <chr>
1 1/1/2010 Low High Low <NA>
2 Time 2:58 AM 9:38 AM 5:19 PM <NA>
3 Tide 1.2 2.2 0.6 <NA>
4 1/2/2011 High Low High Low
5 Time 2:07 AM 4:22 AM 10:19 AM 6:07 PM
6 Tide 1.4 1.3 2.3 0.4
DF <- DF %>%
mutate(Date = as.Date(gsub("Tide|Time","", C1), format = "%d/%m/%Y"))
DF <- DF %>%
mutate(Date = na.locf(DF$Date, na.rm = TRUE),
C1 = gsub("[[:digit:]]|\\/", "", C1),
Type = if_else(nchar(C1) == 0, "TideType", C1)) %>%
select(Date, Type, C2:C5) %>%
gather(oColumn, Value, -c(Date, Type)) %>%
spread(key = Type, value = Value) %>%
select(Date, Time, Tide) %>%
filter(complete.cases(.))
DF <- DF %>%
mutate(Time = ymd_hm(paste(DF$Date, DF$Time, sep = " ")),
Tide = as.numeric(Tide))
DF <- DF %>%
mutate(DayNight = (DF$Time) %within%
interval(as.POSIXlt(DF$Date) + (7*60*60), as.POSIXlt(DF$Date) + (19*60*60))) %>%
filter(DayNight == TRUE) %>%
select(-DayNight) ) %>%
group_by(Date) %>%
filter(Tide == max(Tide) | min(Tide))
DF
Source: local data frame [4 x 3]
Groups: Date [2]
Date Time Tide
<date> <dttm> <dbl>
1 2010-01-01 2010-01-01 09:38:00 2.2
2 2010-01-01 2010-01-01 17:19:00 0.6
3 2011-02-01 2011-02-01 10:19:00 2.3
4 2011-02-01 2011-02-01 18:07:00 0.4
请注意,“Date”是Object的Date类型,“Time”是Date-Time Object的Posixct类型。您可能希望将“时间”转换为分钟向量。