在R中代码循环的快速有效方法

时间:2017-07-19 01:57:46

标签: r

我希望以有效的方式运行以下循环,因为我需要在数百万行上执行此操作。 样本数据

a <- data.frame(x1=rep(c('a','b','c','d'),5),
                x2=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5),
                value1=c(rep(201,4),rep(202,4),rep(203,4),rep(204,4),rep(205,4)),
                y1=c(rep('a',4),rep('b',4),rep('c',4),rep('d',4),rep('e',4)),
                y2=c(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7,5,6,7,8),
                value2=seq(101,120), stringsAsFactors = FALSE)

我在下面写了比较两列之间的相似值,然后找出差异。

for (i in 1:length(a$x1)){
  for (j in 1:length(a$x1)){
    if(a$y1[i] == a$x1[j] & a$y2[i] == a$x2[j]){
      a$diff[i] <- a$value1[j] - a$value2[i]
      break
    }
  }
}

1 个答案:

答案 0 :(得分:0)

对于每个i,您要找到a$y1[i] == a$x1[j] && a$y2[i] == a$x2[j]的第一个j(在您的代码中,&代替&&,这显然是错误的。)

如果a$x1a$x2a$y1a$y2是不带空格的数字或字符数据(如示例所示),则可以使用

x12 = paste(a$x1, a$x2)
y12 = paste(a$y1, a$y2) 

然后对于每个i,你要找到第一个j x12[i]==y12[j]

您使用match(x12, y12)执行此操作。

所以你可以这样做:

x12 = paste(a$x1, a$x2)
y12 = paste(a$y1, a$y2) 
m = match(x12, y12)
for (i in seql(m))
    if (!is.na(m[i]))
        a$diff[i] <- a$value1[m[i]] - a$value2[i]

你可以像这样消除最后一个循环:

x12 = paste(a$x1, a$x2)
y12 = paste(a$y1, a$y2) 
m = match(x12, y12)
good.i = which(!is.na(m))
a$diff[good.i] <- a$value1[m[good.i]] - a$value2[good.i]