计算后续天数之间没有for循环的差异

时间:2017-02-22 11:59:34

标签: r

我有以下数据框:

time <- c("2004-01-01 01:30:00","2004-01-01 04:30:00","2004-01-01 07:30:00",
          "2004-01-01 10:30:00","2004-01-01 13:30:00","2004-01-01 16:30:00",
          "2004-01-01 19:30:00","2004-01-01 22:30:00","2004-01-02 01:30:00",
          "2004-01-02 04:30:00","2004-01-02 07:30:00","2004-01-02 10:30:00",
          "2004-01-02 13:30:00","2004-01-02 16:30:00","2004-01-02 19:30:00",
          "2004-01-02 22:30:00","2004-01-03 01:30:00","2004-01-03 04:30:00",
          "2004-01-03 07:30:00","2004-01-03 10:30:00")
d <- c(0.00, 0.00,152808.30, 739872.84, 82641.22, 83031.04, 83031.04, 82641.22, 0.00, 
       0.00, 267024.71,1247414.7, 151638.85, 151249.03, 151249.03, 152028.67, 0.00, 0.00, 
       296650.81,1355783.85)
dat <- data.frame(time = time, dat = d)

显示了预测模型中3天的太阳辐射累积(每天)。

要将太阳辐射单位从J / m2转换为W / m2,我需要计算每天不同预测时间之间的差值并除以10800(预测时间)。这是我的尝试:

itime <- as.numeric(as.Date(dat$time))
utime <- unique(itime)
l <- list()
for(i in 1:length(utime)){
  idx <- itime == utime[i]
  dat2 <- dat[idx,]
  dat3 <- dat2[1,2]/10800
  for(ii in 2:nrow(dat2)){
    dat3[ii] <- (abs(dat2[ii,2] - dat2[ii-1,2]))/10800
  }
  df <- data.frame(dateTime = dat2$time,
                   dd = dat3)
  l[[i]] <- df
}
df1 <- do.call(rbind.data.frame, l)
df1[,1] <- as.POSIXct(df1[,1])

按预期执行。但是,我打算使用此代码的实际数据的长度大于100天。因此,运行循环不是最佳的。

我可以使用另一种方法而不是循环吗?

我试过了:

dat2 <- c(dat[1,2]/10800,rev(abs(diff(rev(dat[,2])))/10800))
df2 <- data.frame(time = as.POSIXct(dat[,1]), dd = dat2)

它给出了几乎相同的答案(如循环),但它也计算了不同日期的时间步长之间的差异,而不是将计算分离到各个日期。

plot(df1, type = 'l')
lines(df2, col = 'red')

正如您所看到的,在凌晨时分不匹配。

有人可以建议另一种方法吗?

2 个答案:

答案 0 :(得分:1)

使用可以使用lag() dplyrgroup_by()

library(dplyr) df <- dat %>% mutate(date = as.Date(time)) %>% group_by(date) %>% mutate(before.dat = lag(dat, order_by=date)) %>% mutate(diff = abs(dat - before.dat)/10800) %>% select(time, date, dat, before.dat, diff) df #Source: local data frame [20 x 5] #Groups: date [3] # time date dat before.dat diff # <fctr> <date> <dbl> <dbl> <dbl> #1 2004-01-01 01:30:00 2004-01-01 0.00 NA NA #2 2004-01-01 04:30:00 2004-01-01 0.00 0.00 0.00000000 #3 2004-01-01 07:30:00 2004-01-01 152808.30 0.00 14.14891667 #4 2004-01-01 10:30:00 2004-01-01 739872.84 152808.30 54.35782778 #5 2004-01-01 13:30:00 2004-01-01 82641.22 739872.84 60.85477963 #6 2004-01-01 16:30:00 2004-01-01 83031.04 82641.22 0.03609444 #7 2004-01-01 19:30:00 2004-01-01 83031.04 83031.04 0.00000000 #8 2004-01-01 22:30:00 2004-01-01 82641.22 83031.04 0.03609444 #9 2004-01-02 01:30:00 2004-01-02 0.00 NA NA #10 2004-01-02 04:30:00 2004-01-02 0.00 0.00 0.00000000 #11 2004-01-02 07:30:00 2004-01-02 267024.71 0.00 24.72451019 #12 2004-01-02 10:30:00 2004-01-02 1247414.70 267024.71 90.77685093 #13 2004-01-02 13:30:00 2004-01-02 151638.85 1247414.70 101.46072685 #14 2004-01-02 16:30:00 2004-01-02 151249.03 151638.85 0.03609444 #15 2004-01-02 19:30:00 2004-01-02 151249.03 151249.03 0.00000000 #16 2004-01-02 22:30:00 2004-01-02 152028.67 151249.03 0.07218889 #17 2004-01-03 01:30:00 2004-01-03 0.00 NA NA #18 2004-01-03 04:30:00 2004-01-03 0.00 0.00 0.00000000 #19 2004-01-03 07:30:00 2004-01-03 296650.81 0.00 27.46766759 #20 2004-01-03 10:30:00 2004-01-03 1355783.85 296650.81 98.06787407
dat %>%
    mutate(time = as.Date(time)) %>%
    group_by(time) %>%
    mutate(diff = (dat-lag(dat)) / 10800)

基于GGamba评论的简化代码

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:ads="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.uzerjamal.cricketscoremanager.MainActivity" android:background="#E9E9E9" android:orientation="vertical">
 <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
  <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.05" android:orientation="horizontal">
    <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical">
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
    </LinearLayout>
    <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#9E9E9E" android:alpha="0.50" />
    <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical">
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
        <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BUTTONeeee" android:layout_marginTop="0dp" android:layout_marginRight="4dp" android:layout_marginLeft="4dp" android:layout_marginBottom="4dp" android:textColor="@android:color/black" android:alpha="0.87" android:backgroundTint="#FF9800" />
  </LinearLayout>
 </LinearLayout>
</LinearLayout>

答案 1 :(得分:1)

对于您的列表l,您可以通过

获得相同的结果
dat <- data.frame(
time = c("2004-01-01 01:30:00","2004-01-01 04:30:00","2004-01-01 07:30:00",
          "2004-01-01 10:30:00","2004-01-01 13:30:00","2004-01-01 16:30:00",
          "2004-01-01 19:30:00","2004-01-01 22:30:00","2004-01-02 01:30:00",
          "2004-01-02 04:30:00","2004-01-02 07:30:00","2004-01-02 10:30:00",
          "2004-01-02 13:30:00","2004-01-02 16:30:00","2004-01-02 19:30:00",
          "2004-01-02 22:30:00","2004-01-03 01:30:00","2004-01-03 04:30:00",
          "2004-01-03 07:30:00","2004-01-03 10:30:00"),
dat = c(0.00, 0.00,152808.30, 739872.84, 82641.22, 83031.04, 83031.04, 82641.22, 0.00, 
       0.00, 267024.71,1247414.7, 151638.85, 151249.03, 151249.03, 152028.67, 0.00, 0.00, 
       296650.81,1355783.85)
)

dat$itime <- as.numeric(as.Date(dat$time))
utime <- unique(dat$itime)

daydat <- function(u) { 
  dat2 <- dat[dat$itime==u,]
  data.frame(dateTime = dat2$time, dd = c(dat2$dat[1], abs(diff(dat2$dat)))/10800)
}
l <- lapply(utime, daydat)

以下是split()的版本:

dat$itime <- as.numeric(as.Date(dat$time))

daydat <- function(d) data.frame(dateTime = d$time, dd = c(d$dat[1], abs(diff(d$dat)))/10800)

L <- split(dat, dat$itime)
l <- lapply(L, daydat)

或不创建dat$itime

daydat <- function(d) data.frame(dateTime = d$time, dd = c(d$dat[1], abs(diff(d$dat)))/10800)
l <- lapply(split(dat, as.Date(dat$time)), FUN=daydat)

或使用by()

l2 <- unclass(by(dat, as.Date(dat$time), FUN=daydat))

如果您希望将结果包含在原始数据框中,可以使用ave()

dat$dd <- ave(dat$dat, as.Date(dat$time), FUN=function(x) c(x[1], abs(diff(x)))/10800)