Sherlock
Sherlock

Reputation: 5627

NA values in concatenated R vectors

Consider the following code

MyClass <- setRefClass("MyClass",

                          fields = list(body = "vector"),

                          methods = list(
                            initialize = function(length){
                              body <<- sample(-100:100, length) / 100
                            }
                          )
)

myFunction <- function(classA, classB){
    cut <- sample(1:length(classA$body), 1)
    new.bodyA <- c(classA$body[1:cut], classB$body[cut+1:length(classB$body)])
    new.bodyB <- c(classB$body[1:cut], classA$body[cut+1:length(classA$body)])
    classA$body <- new.bodyA
    classB$body <- new.bodyB
    return(list(classA, classB))
}

a <- MyClass$new(10)
b <- MyClass$new(10)

myFunction(a, b)

What I am trying to achieve is two new vectors that combine the elements of two given vectors based on a random element index.

I am not sure what is happening, but when I run this the new vectors will contain NA values:

[[1]]
Reference class object of class "MyClass"
Field "body":
 [1]  0.50 -0.67  0.69 -0.43  0.12 -0.82  0.76  0.72 -0.02 -0.31    NA    NA    NA    NA    NA    NA    NA

[[2]]
Reference class object of class "MyClass"
Field "body":
 [1]  0.18  0.41  0.11  0.14  0.52 -0.67 -0.30 -0.85 -0.45  0.33    NA    NA    NA    NA    NA    NA    NA

I am not sure why this is happening - the function works correctly but I don't know how to avoid the NA values. Can someone explain why this is happening, and suggest a workaround ?

Many thanks

Upvotes: 0

Views: 104

Answers (2)

flodel
flodel

Reputation: 89057

I am pretty sure that the problem in your code is when you use

cut+1:length(classB$body)

while you should be using:

(cut+1):length(classB$body)

These are not the same thing because the : operator has higher precedence than the binary + (See ?Syntax for detail on operator precedence). See for yourself:

2+1:6
# [1] 3 4 5 6 7 8
2+(1:6)
# [1] 3 4 5 6 7 8
(2+1):6
# [1] 3 4 5 6

Upvotes: 3

Michael
Michael

Reputation: 2867

 a = c(1,2,3,4,5)
 b = c(6,7,8,9,10)

 concat_a_wrong = c(a[1:3],b[3+1:length(b)])
 concat_a_correct  = c(a[1:3],b[(3+1):length(b)])



 >>concat_a_wrong 
 1  2  3  9 10 NA NA NA
 >>concat_a_correct  
 1  2  3  9 10

in the wrong case you add the cut to every item in range 1:length so actually you go out bounds (NA) in the b array

Upvotes: 1

Related Questions