2016-05-30 4 views
0

Я пытаюсь извлечь дневной минимальный зенитный угол в наборе данных, который состоит из 24-часовых значений (1 значение зенитного угла каждый час) в течение ~ 31 дня в течение 12 месяцев. Это выглядит следующим образом:Суточные минимальные значения в R

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 выходов)?

ответ

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. Просто FYI, даже если это разрешено, не считайте хорошей практикой содержать пространство в имени столбца.

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 
1

С dplyr

library(dplyr) 
df %>% 
    group_by(JulianDay) %>% #if you need `Date` class, use `as.Date(JulianDay)` 
    summarise(MaxZenith = max(Zenith), minZenith = min(Zenith)) 

где «JulianDay» - это имя переименованного столбца для (YYMMDD HH:MM:SS)