我试图在一个数据集中提取每日最小天顶角,该数据集包括24小时值(每小时1个天顶角值),持续12个月~31天。它看起来像这样:
JulianDay Azimuth Zenith Date (YYMMDD HH:MM:SS)
2455928 174.14066 70.04650 2012-01-01 13:00:00
2455928 188.80626 70.30747 2012-01-01 14:00:00
2455928 203.03458 73.12297 2012-01-01 15:00:00
2455928 216.28061 78.20131 2012-01-01 16:00:00
2455928 228.35929 85.10759 2012-01-01 17:00:00
....
2456293 146.33844 77.03456 2012-12-31 11:00:00
2456293 159.80472 72.38003 2012-12-31 12:00:00
是否有能够从每天提取最大和最小太阳天顶角的功能(即365输出)?
答案 0 :(得分:3)
您可以按天分组,这是一种方式,假设您的数据框被称为df
:
library(data.table)
setDT(df)[, .(maxZenith = max(Zenith), minZenith = min(Zenith)), .(JulianDay)]
如果您想使用Date
列而不是JulianDay
,请执行以下操作:
setDT(df)[, .(maxZenith = max(Zenith), minZenith = min(Zenith)), .(as.Date(Date))]
假设您将Date (YYMMDD HH:MM:SS)
重命名为Date
。仅供参考,即使允许,也不要认为在列名中包含空格是一种很好的做法。
答案 1 :(得分:3)
在基地R
:
my.data <- read.table(text = '
JulianDay Azimuth Zenith Date.YYMMDD Date.HHMMSS
2455928 174.14066 70.04650 2012-01-01 13:00:00
2455928 188.80626 70.30747 2012-01-01 14:00:00
2455928 203.03458 73.12297 2012-01-01 15:00:00
2455928 216.28061 78.20131 2012-01-01 16:00:00
2455928 228.35929 85.10759 2012-01-01 17:00:00
2455929 160.00000 70.04650 2012-01-02 13:00:00
2455929 188.80626 70.30747 2012-01-02 14:00:00
2455929 203.03458 73.12297 2012-01-02 15:00:00
2455929 216.28061 78.20131 2012-01-02 16:00:00
2455929 228.35929 85.10759 2012-01-02 17:00:00
', header = TRUE)
with(my.data, aggregate(Azimuth ~ JulianDay, FUN = function(x) c(Min = min(x), Max = max(x))))
aggregate
的一个问题是输出不是易于使用的表单。它需要一些后期处理:
my.min.max <- with(my.data, aggregate(my.data$Azimuth, by = list(my.data$JulianDay),
FUN = function(x) c(MIN = min(x), MAX = max(x)) ))
# to convert output of aggregate into a data frame:
my.min.max2 <- do.call(data.frame, my.min.max)
# combine output from aggregate with original data set
colnames(my.min.max2) <- c('JulianDay', 'my.min', 'my.max')
my.data2 <- merge(my.data, my.min.max2, by = 'JulianDay')
my.data2
# JulianDay Azimuth Zenith Date.YYMMDD Date.HHMMSS my.min my.max
#1 2455928 174.1407 70.04650 2012-01-01 13:00:00 174.1407 228.3593
#2 2455928 188.8063 70.30747 2012-01-01 14:00:00 174.1407 228.3593
#3 2455928 203.0346 73.12297 2012-01-01 15:00:00 174.1407 228.3593
#4 2455928 216.2806 78.20131 2012-01-01 16:00:00 174.1407 228.3593
#5 2455928 228.3593 85.10759 2012-01-01 17:00:00 174.1407 228.3593
#6 2455929 160.0000 70.04650 2012-01-02 13:00:00 160.0000 228.3593
#7 2455929 188.8063 70.30747 2012-01-02 14:00:00 160.0000 228.3593
#8 2455929 203.0346 73.12297 2012-01-02 15:00:00 160.0000 228.3593
#9 2455929 216.2806 78.20131 2012-01-02 16:00:00 160.0000 228.3593
#10 2455929 228.3593 85.10759 2012-01-02 17:00:00 160.0000 228.3593
您也可以使用by
,但by
的输出也需要进行一些后期处理:
by.min.max <- as.data.frame(do.call("rbind", by(my.data$Azimuth, my.data$JulianDay,
FUN = function(x) c(Min = min(x), Max = max(x)))))
by.min.max <- cbind(JulianDay = rownames(by.min.max), by.min.max)
my.data2 <- merge(my.data, by.min.max, by = 'JulianDay')
my.data2
您还可以使用tapply
:
my.data$Date_Time <- as.POSIXct(paste(my.data$Date.YYMMDD, my.data$Date.HHMMSS),
format = "%Y-%d-%m %H:%M:%S")
ty.min.max <- as.data.frame(do.call("rbind", tapply(my.data$Azimuth, my.data$JulianDay,
FUN = function(x) c(Min = min(x), Max = max(x)))))
ty.min.max <- cbind(JulianDay = rownames(ty.min.max), ty.min.max)
my.data2 <- merge(my.data, ty.min.max, by = 'JulianDay')
my.data2
您还可以使用split
和sapply
的组合:
sy.min.max <- t(sapply(split(my.data$Azimuth, my.data$JulianDay),
function(x) c(Min = min(x), Max = max(x)) ))
sy.min.max <- data.frame(JulianDay = rownames(sy.min.max), sy.min.max,
stringsAsFactors = FALSE)
my.data2 <- merge(my.data, sy.min.max, by = 'JulianDay')
my.data2
您还可以使用split
和lapply
的组合:
ly.min.max <- lapply(split(my.data$Azimuth, my.data$JulianDay),
function(x) c(Min = min(x), Max = max(x)))
ly.min.max <- as.data.frame(do.call("rbind", ly.min.max))
ly.min.max <- cbind(JulianDay = rownames(ly.min.max), ly.min.max)
my.data2 <- merge(my.data, ly.min.max, by = 'JulianDay')
my.data2
你也可以使用ave
,虽然我还没想出如何在一个ave
语句中使用两个函数:
my.min <- ave(my.data$Azimuth, my.data$JulianDay, FUN = min)
my.max <- ave(my.data$Azimuth, my.data$JulianDay, FUN = max)
my.data2 <- data.frame(my.data, my.min, my.max)
my.data2
答案 2 :(得分:1)
使用library(dplyr)
df %>%
group_by(JulianDay) %>% #if you need `Date` class, use `as.Date(JulianDay)`
summarise(MaxZenith = max(Zenith), minZenith = min(Zenith))
(YYMMDD HH:MM:SS)
其中'JulianDay'是QObject