The condition has length > 1 and only the first element will be used. What changes to make?

后端 未结 2 1163
夕颜
夕颜 2020-12-07 06:12

When i run the below function, i get the output for just one value. with a message, \"the condition has length > 1 and only the first element will be used\"

What cha

相关标签:
2条回答
  • 2020-12-07 06:20

    The other way to vectorize this function is to use ifelse instead of if:

    ownsquare2 <- function(n)
    {
        for (i in seq(from = 1, to = 506, by = 0.001))
        {
            r <- i * i
            x <- ifelse(r <= n, i, x)
        }
        x 
    }
    ownsquare2(1:10)
    ## [1] 1.000 1.414 1.732 2.000 2.236 2.449 2.645 2.828 3.000 3.162
    

    Here, x is treated as a vector in the function, and the substitution used in the if expression is vectorized with ifelse.

    The translation from if to ifelse is fairly straightforward, but becomes unreadable (IMO) for chained if-else code.

    0 讨论(0)
  • 2020-12-07 06:38

    You are trying to create a function that can do the same operation on multiple values, returning a vector of equal length as its argument. In R parlance that behavior of a function is known as "vectorization". And there is a wrapper function around the mapply function that is named Vectorize. This illustrates its use with your function which does work correctly on a single element:

     Vownsquare <- Vectorize(ownsquare)
     Vownsquare( 1:10 )
     #-------
     [1] 1.000 1.414 1.732 2.000 2.236 2.449 2.645 2.828 3.000 3.162
    

    It's really slow, but this is the result of an inefficient implementation. Might improve your efficiency by learning to use break. This avoids the unnecessary iteration after the condition r>n is reached.

     ownsquare <- function(n)
     {
       for (i in seq(from = 1, to = 506, by = 0.001))
       {
         r <- i * i
         if (r > n) { x=i; break() }
       }
      x 
     }
     Vownsquare <- Vectorize(ownsquare)
     Vownsquare( 1:10 )
    [1] 1.001 1.415 1.733 2.001 2.237 2.450 2.646 2.829 3.001 3.163
    

    Notice this comparison of Lundberg's implementation that computes the full 506,000 length vector for each argument:

     system.time(ownsquare2(1:10))   # makes full vectors
       user  system elapsed 
      7.311   0.069   7.292 
    
     system.time(ownsquare(1:10))    # uses break
       user  system elapsed 
      0.008   0.000   0.008 
    
     system.time(Vownsquareoriginal( 1:10 ))  # full vectors with if()
       user  system elapsed 
      3.746   0.040   3.729 
    
    0 讨论(0)
提交回复
热议问题