R 使用 for 循环填充向量的问题

发布于 2024-10-08 02:26:36 字数 1650 浏览 0 评论 0原文

我正在迭代一个向量,对于每个元素,我按行名在表中查找内容并将返回值复制到不同的向量中。下面的代码用于

gs1 = function(p)
{
output <- character() #empty vector to which results will be forwarded

for (i in 1:length(p)) {
test <- p[i]
index <- which(rownames(conditions) == test)
toappend <- conditions[index,3] #working
output[i] <- toappend
print(paste(p[i],index,toappend,output[i]))
}   
return(output)
}

它吐出的只是一个带有数字的向量......而所有其他变量似乎都包含正确的信息(如打印函数所检查) 我感觉我在填充输出向量时做了一些非常错误的事情...我也可以使用

output <- c(output,toappend)

但这给了我完全相同的、错误的和奇怪的输出。

非常感谢所有帮助!

输出示例

> gs1 = function(p)
+ {
+ output <- character() #empty vector to which results will be pasted
+ 
+ for (i in 1:length(p)) {
+ test <- p[i]
+ index <- which(rownames(conditions) == test)
+ toappend <- conditions[index,3] #working
+ 
+ output <- c(output,toappend)
+ output[i] <- toappend
+ print(paste(p[i],index,toappend,output[i],sep=","))
+ }
+ return(output)
+ }
> ###########################
> test <- colnames(tri.data.1)
> gs1(test)
[1] "Row.names,,,NA"
[1] "GSM235482,1,Glc A,5"
[1] "GSM235484,2,Glc A,5"
[1] "GSM235485,3,Glc A,5"
[1] "GSM235487,4,Xyl A,21"
[1] "GSM235489,5,Xyl A,21"
[1] "GSM235491,6,Xyl A,21"
[1] "GSM297399,7,pH 2.5,12"
[1] "GSM297400,8,pH 2.5,12"
[1] "GSM297401,9,pH 2.5,12"
[1] "GSM297402,10,pH 4.5,13"
[1] "GSM297403,11,pH 4.5,13"
[1] "GSM297404,12,pH 4.5,13"
[1] "GSM297563,13,pH 6.0,14"
[1] "GSM297564,14,pH 6.0,14"
[1] "GSM297565,15,pH 6.0,14"
 [1] "5"  "5"  "5"  "5"  "21" "21" "21" "12" "12" "12" "13" "13" "13" "14" "14" "14"

I'm iterating over a vector, for each element I look something up in a table by rowname and copy the return into a different vector. The following code is used for that

gs1 = function(p)
{
output <- character() #empty vector to which results will be forwarded

for (i in 1:length(p)) {
test <- p[i]
index <- which(rownames(conditions) == test)
toappend <- conditions[index,3] #working
output[i] <- toappend
print(paste(p[i],index,toappend,output[i]))
}   
return(output)
}

All it spits out is a vector with numbers....while all other variables seems to contain the correct information (as checked by the print function)
I have the feeling I'm doing something terribly wrong in filling the output vector... I could also use

output <- c(output,toappend)

But that gives me exactly the same, wrong and strange output.

All help is very much appreciated!

Output example

> gs1 = function(p)
+ {
+ output <- character() #empty vector to which results will be pasted
+ 
+ for (i in 1:length(p)) {
+ test <- p[i]
+ index <- which(rownames(conditions) == test)
+ toappend <- conditions[index,3] #working
+ 
+ output <- c(output,toappend)
+ output[i] <- toappend
+ print(paste(p[i],index,toappend,output[i],sep=","))
+ }
+ return(output)
+ }
> ###########################
> test <- colnames(tri.data.1)
> gs1(test)
[1] "Row.names,,,NA"
[1] "GSM235482,1,Glc A,5"
[1] "GSM235484,2,Glc A,5"
[1] "GSM235485,3,Glc A,5"
[1] "GSM235487,4,Xyl A,21"
[1] "GSM235489,5,Xyl A,21"
[1] "GSM235491,6,Xyl A,21"
[1] "GSM297399,7,pH 2.5,12"
[1] "GSM297400,8,pH 2.5,12"
[1] "GSM297401,9,pH 2.5,12"
[1] "GSM297402,10,pH 4.5,13"
[1] "GSM297403,11,pH 4.5,13"
[1] "GSM297404,12,pH 4.5,13"
[1] "GSM297563,13,pH 6.0,14"
[1] "GSM297564,14,pH 6.0,14"
[1] "GSM297565,15,pH 6.0,14"
 [1] "5"  "5"  "5"  "5"  "21" "21" "21" "12" "12" "12" "13" "13" "13" "14" "14" "14"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

腻橙味 2024-10-15 02:26:36

您很可能使用数据框而不是表格,并且您的第三列很可能不是字符向量而是一个因子。并且无需编写该函数,您可以轻松获得所需的内容:

conditions[X,3]

其中 X 是行名称的字符向量。例如:

X <- data.frame(
  var1 = 1:10,
  var2 = 10:1,
  var3 = letters[1:10],
  row.names=LETTERS[1:10]
)
> test <- c("F","D","A")
> X[test,3]
[1] f d a
Levels: a b c d e f g h i j

要以字符形式获取它:

> as.character(X[test,3])
[1] "f" "d" "a"

Very likely you're using a data frame and not a table, and as likely your third column is not a character vector but a factor. And there is no need to write that function, you could easily obtain the wanted by:

conditions[X,3]

with X being a character vector of row names. eg :

X <- data.frame(
  var1 = 1:10,
  var2 = 10:1,
  var3 = letters[1:10],
  row.names=LETTERS[1:10]
)
> test <- c("F","D","A")
> X[test,3]
[1] f d a
Levels: a b c d e f g h i j

To get it in characters:

> as.character(X[test,3])
[1] "f" "d" "a"
一笔一画续写前缘 2024-10-15 02:26:36

[Joris 的评论表明我太神秘了,所以需要一些额外的解释]:

实际上,如果我们忽略循环中的处理,这就是你所拥有的:

> p <- 1:10
> gs1 <- function(p) {
+     output <- character()
+     for(i in seq_along(p))  {
+         output[i] <- p[i] * 10
+         print(output)
+     }
+     return(output)
+ }
> foo <- gs1(p)
[1] "10"
[1] "10" "20"
[1] "10" "20" "30"
[1] "10" "20" "30" "40"
[1] "10" "20" "30" "40" "50"
[1] "10" "20" "30" "40" "50" "60"
[1] "10" "20" "30" "40" "50" "60" "70"
[1] "10" "20" "30" "40" "50" "60" "70" "80"
[1] "10" "20" "30" "40" "50" "60" "70" "80" "90"
[1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"
> foo
[1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"

所以 gs1 返回一些东西,并且 只要 toappend 是一个字符或者可以强制为字符以进入output,output 就会被填充。现在,如果 toappend 不是您想象的那样,那么您就会开始遇到问题。

我看到两个潜在的问题; i) toappend 实际上是一个因素(Joris 也提到过),您将获得该级别的内部编码的等效数字。在这种情况下

ouput[i] <- as.character(toappend)

应该足够了,或者 ii) index 大于长度 1 并且您在向量中获得了您期望的更多元素,因此在下一次迭代时您将覆盖它们。

确定 toappend 是长度为 1 的单个字符向量吗?您向我们展示不正确的输出(编辑您的问题并添加函数的输出)并告诉我们为什么它是错误的怎么样?

当然,这都可以简化为 conditions[p, 3] 并且不需要循环,但我认为您的实际功能更复杂?


设置循环的注意事项

对于一般的循环,您会犯不预先分配存储的错误。你不应该按照你现在的方式做事。请注意,在每次迭代中,R 都必须将输出增加一个元素。您的 output <- c(output, toappend) 习惯用法也是如此。这涉及到向量的大量冗余复制,从而导致循环下降。相反,请预先分配足够的存储空间并按照您正在执行的操作填充输出。例如:

gs2 <- function(p) {
    output <- character(length = length(p))
    for(i in seq_along(p))  {
        output[i] <- p[i] * 10
        print(output)
    }
    return(output)
}

产生以下输出:

> gs2(p)
 [1] "10" ""   ""   ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" ""   ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" "80" ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" "80" "90" ""  
 [1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"
 [1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"

重复的最后一行是由于自动打印从函数返回的对象(输出)而导致的。

[Joris' comments suggest I was too cryptic, so some additional explanation]:

Effectively, if we ignore the processing in your loop, this is what you have:

> p <- 1:10
> gs1 <- function(p) {
+     output <- character()
+     for(i in seq_along(p))  {
+         output[i] <- p[i] * 10
+         print(output)
+     }
+     return(output)
+ }
> foo <- gs1(p)
[1] "10"
[1] "10" "20"
[1] "10" "20" "30"
[1] "10" "20" "30" "40"
[1] "10" "20" "30" "40" "50"
[1] "10" "20" "30" "40" "50" "60"
[1] "10" "20" "30" "40" "50" "60" "70"
[1] "10" "20" "30" "40" "50" "60" "70" "80"
[1] "10" "20" "30" "40" "50" "60" "70" "80" "90"
[1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"
> foo
[1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"

So gs1 is returning something, and output is being filled, as long as toappend is acharacter or can be coerced to character to go into output. Now, if toappend is not what you think it is, then that is where you will start to get problems.

I see two potential problems; i) toappend is actually a factor (which is something Joris mentions too) and you are getting the numerical equivalent of the internal coding for that level. In which case

ouput[i] <- as.character(toappend)

should suffice, or ii) index is greater than length 1 and you are getting more elements in the vector that you expect and thus at the next iteration you are overwriting them.

Are you sure toappend is a single character vector of length 1? How about you show us the incorrect output (edit your Question and add the output from the function) and tell us why it is wrong!

Of course, this can all be simplified to conditions[p, 3] and no need for a loop but I assume your actual functions is more complex?


Note on setting up loops

As for loops in general, you make the mistake of not preallocating storage. You shouldn't do things the way you are. Notice how at each iteration R is having to grow output by one element per iteration. The same would be true of your output <- c(output, toappend) idiom. This involves lots of redundant copying of the vector which bogs loops down. Instead, allocate enough storage up front and fill output as you are doing. E.g.:

gs2 <- function(p) {
    output <- character(length = length(p))
    for(i in seq_along(p))  {
        output[i] <- p[i] * 10
        print(output)
    }
    return(output)
}

which produces this output:

> gs2(p)
 [1] "10" ""   ""   ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" ""   ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" ""   ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" ""   ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" ""   ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" ""   ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" ""   ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" "80" ""   ""  
 [1] "10" "20" "30" "40" "50" "60" "70" "80" "90" ""  
 [1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"
 [1] "10"  "20"  "30"  "40"  "50"  "60"  "70"  "80"  "90"  "100"

The duplicated last line is due to auto-printing of the object (output) returned from the function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文