# Making a for loop to count crimes within a certain distance

I'm working on a project that involves counting how many crimes of a certain type happen within 150 meters or 500 meters of a list of addresses. While I've been able to do this successfully without a for-loop, it's a bit cumbersome because of the different crime definitions I need to use, so I'm trying to shorten the process a bit.

Right now, here is the general structure of what I'm trying to do (edited):

``````function(input dataframe, distance, output){
for (i in dataframe)
1. create bounding box row i
2. calculate number of intersections of boundingbox and file for two different files, based on the year the address is from
3. return this count
}
``````
``````countcrimes <- function(x, d, output){
for (i in 1:dim(x)[1]){
bbox150m <- st_buffer(x[i,"geometry"], dist = d)
if (x[i,]\$year == 1){
vc150m <- st_intersection(x = bbox150m, y = crime1516_v)
output[i,] <- vc150m %>%
group_by()
count()
} else if(x[i,]\$year == 2){
vc150m <- st_intersection(x = bbox150m, y = crime1617_v)
output[i,] <- vc150m %>%
group_by() %>%
count()
}
}
return(output)
}

data_sf\$vc150m <- countcrimes(data_sf, 150, vc150m)
``````

The error I'm getting right now is

``````Error in .subset2(x, i, exact = exact) :
attempt to select less than one element in get1index.
``````

it looks like my function pretty much stops working at the state where I use `st_buffer`. If anyone has any ideas of how I could make a function to go through the dataframe that would be really helpful!

``````Error in .subset2(x, i, exact = exact) : attempt to select less than one element in get1index
9. (function(x, i, exact) if (is.matrix(i)) as.matrix(x)[[i]] else .subset2(x, i, exact = exact))(x, ..., exact = exact)
8. [[.data.frame(obj, attr(obj, "sf_column"))
7. obj[[attr(obj, "sf_column")]]
6. st_geometry.sf(x)
5. st_geometry(x)
4. [.sf(x, i, "geometry")
3. x[i, "geometry"]
2. st_buffer(x[i, "geometry"], dist = d)
1. countcrimes(data_sf, 150, vc150m) `
``````

Edit: per @spacedman's suggestion I did some more debugging (which I stupidly didn't do before) and realized that some earlier issues with `bind_rows` on data_sf was compromising the object's geometry. Function doesn't yet work (facing the error `Error in if (x[i, ]\$year == 1) { : argument is of length zero`) but problem solved for now.

• Some more info on the error: ` Error in .subset2(x, i, exact = exact) : attempt to select less than one element in get1index 9. (function(x, i, exact) if (is.matrix(i)) as.matrix(x)[[i]] else .subset2(x, i, exact = exact))(x, ..., exact = exact) 8. `[[.data.frame`(obj, attr(obj, "sf_column")) 7. obj[[attr(obj, "sf_column")]] 6. st_geometry.sf(x) 5. st_geometry(x) 4. `[.sf`(x, i, "geometry") 3. x[i, "geometry"] 2. st_buffer(x[i, "geometry"], dist = d) 1. countcrimes(data_sf, 150, vc150m) ` – cschwab98 Aug 2 '19 at 15:52
• If you need to update your question use the "edit" button rather than pasting code into comments where it is unformatted and unreadable. I've done this. But now your code in the question doesn't match the error, so please edit the question to update your code to the code that produces this error message. – Spacedman Aug 2 '19 at 18:44
• Also, do some basic debugging. Print `i` to see if its a problem with the first time through the loop or the 27th. Try `st_buffer(data_sf[1, "geometry"], dist = 0.2)` to see if its a problem with that specific data set. – Spacedman Aug 2 '19 at 18:48
• you're totally right, thank you so much for the help and apologies for the silly oversight. – cschwab98 Aug 2 '19 at 19:12

Your problem is that you seem to think that `x[i]` will get the `i`-th row of the data frame so that `x[i]\$year` gets the year of that row. That's wrong. `x[i]` actually gets columns:

``````> x = data.frame(year=1980:1990, z=runif(11))

> x[1]
year
1  1980
2  1981
3  1982
...

> x[2]
z
1  0.7296205
2  0.3403549
...
``````

To select rows in a 2-dimensional structure in R use brackets with an empty column index:

``````> x[1,]
year         z
1 1980 0.7296205
``````

Then either get the column by name:

``````> x[1,]\$year
[1] 1980
> x[2,]\$year
[1] 1981
``````

or in the index itself:

``````> x[3,"year"]
[1] 1982
> x[4,"year"]
[1] 1983
``````

or get the `i`th element of the column with `x\$year[i]`

• That makes sense, but I'm still getting the same error: `Error in .subset2(x, i, exact = exact) : attempt to select less than one element in get1index ` and I'm not sure why - it seems like something is wrong with the bbox command, and it's not recognizing the geometry – cschwab98 Aug 2 '19 at 15:07
• I also tried `bbox150m <- st_buffer(st_geometry(x[i,], dist = d)' -- same error – cschwab98 Aug 2 '19 at 15:12