Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 循环和索引的替代方案?_R_For Loop_Indexing - Fatal编程技术网

R 循环和索引的替代方案?

R 循环和索引的替代方案?,r,for-loop,indexing,R,For Loop,Indexing,我有一个3列的大数据集,订单、卸货、日期数字。每个订单有20年的每日流量值,可以超过100 > head(dat) Order Discharge date 1 0.04712 6574 2 0.05108 6574 3 0.00000 6574 4 0.00000 6574 5 3.54100 6574 6 3.61500 6574 d

我有一个3列的大数据集,订单、卸货、日期数字。每个订单有20年的每日流量值,可以超过100

> head(dat)
      Order Discharge date
         1   0.04712 6574
         2   0.05108 6574
         3   0.00000 6574
         4   0.00000 6574
         5   3.54100 6574
         6   3.61500 6574
    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
对于给定的订单x,我想用该日期x+1和x-1处的排放平均值替换排放值。我一直在用for循环和索引以一种粗糙的方式来做这件事,但处理起来需要一个多小时。我知道一定有更好的办法

    x <- 4
    for(i in min(dat[,3]):max(dat[,3]))
    dat[,2][dat[,3] == i & dat[,1] == x ] <- 
    mean(c(dat[,2][dat[,3] == i & dat[,1] == x + 1], 
    dat[,2][dat[,3] == i & dat[,1] == x - 1]))
    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
若日期为6574的第4号订单中的排放已替换为1.77050。它能工作,但速度慢得可笑

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
我应该明确指出,我不需要对每个订单进行这种计算,但只需要从总共117个订单中选择几个订单(仅8个)。根据答案,我有以下几点

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 

我正试图找到一种方法,仍然只计算所选订单的值,并且陷入了for循环和对日期和订单进行索引的常规中。

我将按照以下方式进行操作:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
确保秩序是一个因素。 对于每个订单,您现在都有一个子问题: 按日期对子数据框进行排序。 每个放电平均值可以矢量生成为: ColmeansCBindcD放电[-1],钠,放电,cNA,放电[-长度放电] 子问题可以通过一个简单的for循环或函数来处理。我宁愿坐火车。 您的数据已重新排列,但您可以轻松地对其重新排序。
对于第2.2点,想象一下,或者用一个简单的向量试试,看看cbind操作的效果。它也迫使你考虑极限情况;第一个和最后一个出院值是如何计算的,没有之前或正在进行的日期。

有几种方法可以解决您的特殊困境,但当遇到缓慢的for循环时,要问的基本问题是,我如何使用矢量化来替换此循环?嗯,也许你应该问我,我应该。。。?第一在您的例子中,您在日期之间循环,但是没有必要显式地这样做,因为只要抓取dat$Order==x的所有行就会隐式地抓取所有日期

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
您发布的数据集只有一个日期,但我可以生成一些假数据来说明:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
generate.data <- function(n.order, n.date){
  dat <- expand.grid(Order=seq_len(n.order), date=seq_len(n.date))
  dat$Discharge <- rlnorm(n.order * n.date)
  dat[, c("Order", "Discharge", "date")]
}

dat <- generate.data(10, 5)

head(dat)
#   Order Discharge date
# 1     1 2.1925563    1
# 2     2 0.4093022    1
# 3     3 2.5525497    1
# 4     4 1.9274013    1
# 5     5 1.1941986    1
# 6     6 1.2407451    1
tail(dat)
#    Order Discharge date
# 45     5 1.4344575    5
# 46     6 0.5757580    5
# 47     7 0.4986190    5
# 48     8 1.2076292    5
# 49     9 0.3724899    5
# 50    10 0.8288401    5
你可以选择出院栏,作业的左边是:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
dat[dat$Order==4, ]$Discharge
# [1] 1.9274013 3.5319072 0.2374532 0.4549798 0.7654059
现在您只需要右侧,它有两个组件:x-1放电和x+1放电。您可以像抓取x放电一样抓取这些:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
dat[dat$Order==4-1, ]$Discharge
# [1] 2.5525497 1.9143963 0.2800546 8.3627810 7.8577635
dat[dat$Order==4+1, ]$Discharge
# [1] 1.1941986 4.6076114 0.3963693 0.4190957 1.4344575
要获得新值,需要平行平均值。R没有pmean函数,但您可以cbind这些函数并采用rowMeans:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
因此,最后你有:

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 
dat[dat$Order==4, ]$Discharge <- rowMeans(cbind(dat[dat$Order==4-1, ]$Discharge,
                                                dat[dat$Order==4+1, ]$Discharge))
您甚至可以使用%in%在所有x值中执行此操作

    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T)) 

请注意,这假设您的数据是有序的。

您选择x的标准是什么?有没有一个外环来确定你没有给我们看的x?这可能是相关的。Order表示河流中测量流量的站点。X-1和X+1基本上是上游站和下游站。我想把平均流量从上行站和下行站的某一天取到当天的中站。我已经分别识别了这些x,有8个,但我可以把它们放在一个向量中,并将其包含在函数中。这是一个很好的开始。我应该明确指出,我不需要对每个订单都进行这种计算,但在总共117个订单中,只有少数几个订单需要计算,只有8个订单需要计算。根据你的回答,我有以下几点。”dat$可能不起作用的新排放。by很少返回要插入data.frame的向量。您的第二个参数by将数据按日期分割-在本例中,您采用的是多个订单的平均值。因为你只有8个订单,你可以做:dat
    dat$NewDischarge <- by(dat$Discharge,dat$date,function(x) 
    colMeans(cbind(c(x[-1],NA), x, 
    c(NA, x[-length(x)])), na.rm=T))