2011-11-25 116 views
-2

如何修改我的代码以更新循环内的变量?更新R中循环内的变量

具体来说,我想要做的东西像下面这样:

myMatrix1 <- read.table(someFile) 
myMatrix2 <- read.table(someFile2) 

for (i in nrow(myMatrix2)) 
{  
    myMatrix3 <- myMatrix1[which(doSomeTest),] 
    myMatrix4 <- rep(myMatrix2$header1,nrow(myMatrix1)) 
    myMatrix5 <- rep(myMatrix2$header2, nrow(myMatrix1))   
    myMatrix6 <- cbind(myMatrix3, myMatrix4, myMatrix5) 
    # *see question 

} 

我怎样才能myMatrix6进行更新,而不是重新分配的cbind(myMatrix3, myMatrix4, myMatrix5)的产品?换言之,如果在第一次迭代(i = 1),得到的myMatrix6:

> 1 1 1 1 
> 2 2 2 2 

和第二次迭代(i = 2),得到的myMatrix的6:

> 3 3 3 3 
> 4 4 4 4 

如何获取的数据帧:

> 1 1 1 1 
> 2 2 2 2 
> 3 3 3 3 
> 4 4 4 4 

UPDATE:(?)

我已经 - 拜迪文和蒂莫的建议 - 有后续ING。但是,下面的代码使我在我的数据集上运行了大约2个小时。有什么方法可以让它跑得更快? (不使用更强大的电脑我可以补充)

# create empty matrix for sedimentation 
myMatrix6 <- data.frame(NA,NA,NA,NA)[0,] 
names(myMatrix6) <- letters[1:4] 

# create empty matrix for bore 
myMatrix7 <- data.frame(NA,NA,NA,NA)[0,] 
names(myMatrix7) <- letters[1:4] 

for (i in 1:nrow(myMatrix2)) 
{  
    # create matrix that has the value of myMatrix1$begin being 
    # situated between the values of myMatrix2begin[i] and myMatrix2finish[i] 
    myMatrix3 <- myMatrix1[which((myMatrix1$begin > myMatrix2$begin[i]) & (myMatrix1$begin < myMatrix2$finish[i])),] 

    myMatrix4 <- rep(myMatrix2$sedimentation, nrow(myMatrix3)) 

    if (is.na(myMatrix2$boreWidth[i])) { 
     myMatrix5 <- rep(NA, nrow(myMatrix3)) 
    } 
    else if (myMatrix2$boreWidth[i] == 0) { 
     myMatrix5 <- rep(TRUE, nrow(myMatrix3)) 
    } 
    else if (myMatrix2$boreWidth[i] > 0) { 
     myMatrix5 <- rep(FALSE, nrow(myMatrix3)) 
    } 

    myMatrix6 <- rbind(myMatrix6, cbind(myMatrix3, myMatrix4)) 
    myMatrix7 <- rbind(myMatrix7, cbind(myMatrix3, myMatrix5)) 
} 
+3

你没有明确说明这些不同的物体有什么关系。 “someVector”在某种程度上与“myMatrix1”有关吗?同样,什么是“someArg”?而赋值给“myMatrix2”将取代它,而不是附加到它。我怀疑你对R做了不正确的声明,因为它不是某种其他语言。 –

+0

_我怀疑你对R有不正确的说法,因为它不是其他语言我不怀疑它。这就是为什么我说_seems_。无论如何,感谢您的有用评论。 – Kaleb

+0

@Kaleb我已编辑您的问题,删除煽动性措辞。请检查是否正确。 – Andrie

回答

1

在代码中,你是不是用矩阵处理(在R的意义上),但数据帧,read.table返回的数据帧。

在任一方式,可以追加一个矩阵/数据帧到另一帧有rbind命令

例如(假设列名匹配),如果

> a = data.frame(x=c(1,2,3),y=c(4,5,6),z=c(7,8,9)) 
> b = data.frame(x=c(4,5),y=c(5,6),z=c(6,7)) 

然后

> rbind(a,b) 
    x y z 
1 1 4 7 
2 2 5 8 
3 3 6 9 
4 4 5 6 
5 5 6 7 

您提供的代码中还有其他一些陷阱。例如

for (i in length(someVector))) 

应该是

for (i in 1:length(someVector))) 

R具有许多功能用于遍历data.frames,载体等,并可以做各种数据变换。大多数情况下,不需要编写for循环。

如果您想提供更多关于您想要做什么的细节,也许我们可以找到一个更简单的解决方案。

编辑:

似乎从您的文章更新,你正在尝试做一些“宽”和“长”格式之间的转换,并筛选出测试失败的一些线路。纠正我,如果我错了。

无论如何,如果是这样的话,你应该检查出reshape命令。此外,还有一个包含极其有用的命令的包reshape,其中包含非常有用的命令meltcast,它们可以非常有效地进行这种转换。此外,还有merge命令对数据帧进行某些“连接”操作。我很确定你的问题可以通过使用上述命令的组合来解决,但它取决于确切的细节。

要使用某些条件过滤行/列,请检查subset命令。

+0

好的。谢谢。你是正确的,我试图过滤掉一些测试失败的行。感谢1:nrow()提示:我错过了。我已经编写了一些代码,可以使用迪文建议的代码,但我认为我的代码有点低效。我会更新问题以显示此内容。 – Kaleb

2

您将myMatrix6初始化为空的data.frame,然后对结果进行rbind(可能效率低下)。如果效率是一个问题,那么您需要预先分配所需的大小,并使用索引填充data.frame中的行。

# Method # 1 code 
myMatrix6 <- data.frame(NA,NA,NA,NA)[0,] 
names(myMatrix6) <- letters[1:4] 

for (i in nrow(myMatrix2)) {  
    myMatrix3 <- myMatrix1[which(doSomeTest),] 
    myMatrix4 <- rep(myMatrix2$header1,nrow(myMatrix1)) 
    myMatrix5 <- rep(myMatrix2$header2, nrow(myMatrix1))   
    myMatrix6 <- rbind(myMatrix6, cbind(myMatrix3, myMatrix4, myMatrix5)) 
          } 
+0

谢谢你的工作。 – Kaleb