簡體   English   中英

應用函數而不是R中的for循環

[英]Apply functions instead of for loop in R

我是R的新手。我想知道我們如何以有效的方式編寫以下for循環。 我通過下面的代碼獲取小型數據集的正確答案。

data <- data.frame(x1=c(rep('a',12)),
            x2=c(rep('b',12)),
            x3=c(rep(as.Date('2017-03-09'),4),rep(as.Date('2017-03-10'),4),rep(as.Date('2017-03-11'),4)),
            value1= seq(201,212),
            x4=c(as.Date('2017-03-09'),as.Date('2017-03-10'),as.Date('2017-03-11'),as.Date('2017-03-12')
                 ,as.Date('2017-03-10'),as.Date('2017-03-11'),as.Date('2017-03-12'),as.Date('2017-03-13')
                 ,as.Date('2017-03-11'),as.Date('2017-03-12'),as.Date('2017-03-13'),as.Date('2017-03-14')),
            value2= seq(101,112), stringsAsFactors = FALSE)

以下為循環腳本:

for (i in 1:length(data$x3)){
  print(i)
  if (!is.na(data$x4[i])){
    if(data$x4[i] == data$x3[i] && data$x2[i]==data$x2[i] && data$x1[i]==data$x1[i]){

      data$diff[i] <- data$value1[i] - data$value2[i]
    }
    else{
      print("I am in else")
      for (j in 1:length(data$x3)){
        print(c(i,j))
        # print(a$y[i])
        if(data$x4[i]==data$x3[j] && data$x1[i]==data$x1[j] && data$x2[i]==data$x2[j]){

          # print(a$x[j])
          data$diff[i] <- data$value1[j] - data$value2[i]
          break
        }
      }
    }
  }
}

你可以這樣做:

data$diff <- sapply(seq_along(data$x3), function(i) {
  if (!is.na(data$x4[i])){
    ind <- which(data$x4[i] == data$x3 & data$x1[i] == data$x1 & data$x2[i] == data$x2)
    j <- `if`(i %in% ind, i, min(ind))
    data$value1[j] - data$value2[i]
  } else {
    NA
  }
})

注意您的代碼中 ,如果$diff列尚不存在,則執行data$diff[1] <- 100會將列的所有值都設為100

如果您想要性能,答案通常是Rcpp。 在Rcpp中翻譯R代碼:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector f_Rcpp(List data) {

  StringVector      x1 = data["x1"]; 
  StringVector      x2 = data["x2"]; 
  NumericVector     x3 = data["x3"];
  NumericVector     x4 = data["x4"];
  NumericVector value1 = data["value1"];
  NumericVector value2 = data["value2"];

  int n = value1.size();
  NumericVector diff(n, NA_REAL);

  int i, j;

  for (i = 0; i < n; i++) {
    Rprintf("%d\n", i);
    if (x4[i] != NA_REAL) {
      if (x4[i] == x3[i]) {
        diff[i] = value1[i] - value2[i];
      } else {
        Rprintf("I am in else\n");
        for (j = 0; j < n; j++) {
          Rprintf("%d %d\n", i, j);
          if (x4[i] == x3[j] && x1[i] == x1[j] && x2[i] == x2[j]) {
            diff[i] = value1[j] - value2[i];
            break;
          }
        }
      }
    }
  }

  return diff;
}

/*** R
f_Rcpp(data)
*/

將其放在.cpp文件中並提供源文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM