user3742846
user3742846

Reputation: 11

Replace element in a vector with a list in R

So, I have a vector, points, that I want to populate with a pair of points, whose x and y coordinates are uniformly distributed between 0 and 1.

Here is my code so far:

n <- 10000
points <- rep(0, n)
for (i in 1:n) {
  a <- list(x=runif(1, 0, 1), y=runif(1, 0, 1))
  b <- list(x=runif(1, 0, 1), y=runif(1, 0, 1))
  replace(points, i, list(a, b))
}

I have tried the following:

n <- 10000
points <- rep(0, n)
for (i in 1:n) {
  a <- list(x=runif(1, 0, 1), y=runif(1, 0, 1))
  b <- list(x=runif(1, 0, 1), y=runif(1, 0, 1))
  points[i] <- list(a, b)
}

As you can see, a is the first point with uniformly distributed x and y, and b is the second point with uniformly distributed x and y. For each i in 1:n, I'm trying to replace the ith element in points with list(a, b); however, I keep on getting the warning "number of items to replace is not a multiple of replacement length", indicating that it's trying to replace the ith element in points with a and b as separate elements, and not replacing it with a single list element containing a and b. Is there any way I can coax it to do what I want?

Upvotes: 1

Views: 557

Answers (3)

denis
denis

Reputation: 5673

This should work. I defined each point a and b as a data frame, as it is more convenient. point is a list of points

points <- list(a = data.frame(x = runif(10000,0,1),y = runif(10000,0,1)), b =data.frame(x = runif(10000,0,1),y = runif(10000,0,1)))

Here the result with 10 points:

> points
$a
            x         y
1  0.69817192 0.4931020
2  0.08508172 0.5187833
3  0.71519413 0.7871234
4  0.87653502 0.0803383
5  0.57951306 0.4365260
6  0.14673983 0.8060857
7  0.80315435 0.2124616
8  0.79790622 0.6328104
9  0.22130415 0.6239957
10 0.99642466 0.2076050

$b
           x           y
1  0.3798732 0.419808119
2  0.5833667 0.002143209
3  0.8335923 0.708020370
4  0.1923296 0.322810176
5  0.9421873 0.190519505
6  0.6633320 0.143258369
7  0.7465269 0.071942890
8  0.6919004 0.627667826
9  0.5362267 0.345617737
10 0.1725097 0.476865279

Upvotes: 0

Kansrekenaar
Kansrekenaar

Reputation: 21

Try to initiate points as a list, using points <- vector(mode="list",length=n).

Edit: And use double square brackets for the replacement (see comment)

Upvotes: 1

konvas
konvas

Reputation: 14346

The function runif is already vectorized, so your code will be much faster if you call runif once. Essentially what you want is to get 4 * n numbers which are uniformly distributed between 0 and 1, so all you need is numbers <- runif(4 * n). You can then structure them as required. Do you actually need to have a list or are you just using it to make the for loop more efficient? For example matrix(numbers, ncol = 4), will give you a matrix (you can interpret the columns as the x coordinate of a, the y coordinate of a, the x coordinate of b, and the y coordinate of b, it doesn't really matter as they are independently sampled). I can be more specific if you post an example with your desired output.

Upvotes: 0

Related Questions