1

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.

4
  • 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
0

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 ith element of the column with x$year[i]

2
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.