I have a SpatialPointsDataFrame with the data of a city and i want to join it with a dbf that contains the population via a common column that they have. How do i do that so the first one has the population.

df <- read.dbf("newyork2014pop.dbf")
 j<-merge(city,df,by="what do i put here?")


df1 <- read.dbf("newyork2013population.dbf")
reclass = function(x){
 ifelse(x < 500, 0,
     ifelse(x < 1000 & x >= 500, 5, 
            ifelse(x > 1000, 10, NA)))

this returns

Error in (function (classes, fdef, mtable)  : 
unable to find an inherited method for function ‘is.projected’ for signature       ‘"data.frame"’
  • 1
    There is a near identical question on Stack Overflow that should help you: stackoverflow.com/a/3652472/1446289
    – Aaron
    Commented Jul 9, 2015 at 20:58
  • That was a good read but im dealing with a dbf here.
    – gsa
    Commented Jul 9, 2015 at 21:07
  • 1
    df <- read.dbf(system.file("files/sids.dbf", package="foreign")[1]) reads the DBF into a dataframe. Then follow the instructions in the provided SO link.
    – Aaron
    Commented Jul 9, 2015 at 21:11
  • 2
    It is no longer necessary to use match. The de facto R standard for joining data is merge. However, the base merge function performs a resort of the rownames of the data.frame and breaks the relationship in the spatial object. More recently, a specialized version of merge was written for sp class objects that fixes this issue. The sp specific merge function is called automatically, based on recognition of the sp object class. Because of this just use merge() to join external data to the @data slot data.frame. Commented Jul 9, 2015 at 21:47
  • 1
    Read the help for merge as the arguments are pretty straightforward. Since your common columns have different names you will need to use the "by.x" and "by.y" arguments or, you could just change the "df" column name to match the other dataset and then it would just be the "by" argument. Commented Jul 9, 2015 at 22:04

2 Answers 2


You can use the merge function as there is now a default method for sp class objects.

Add sp and the sp "meuse" data (SpatialPointsDataFrame)

coordinates(meuse) <- ~x+y

Add "ID" column to "meuse"

meuse@data <- data.frame(ID=1:nrow(meuse), meuse@data)

Create a data.frame "df.new" with "IDS" (note different name) and "y" columns.

df.new <- data.frame(IDS=1:nrow(meuse), y=runif(nrow(meuse)))

Now we can merge "df.new" to "meuse" (@data slot)

meuse <- merge(meuse, df.new, by.x = "ID", by.y = "IDS")
  • i did the last part and says warning "In .local(x, y, ...) : 105 records in y cannot be matched to x" so i thought to add as well the "all.x=T" but didn;t work >
    – gsa
    Commented Jul 10, 2015 at 10:33
  • That means that not all of your records in "city" are present in "df". BTW, watch your object names. There is an R function in base called df. Commented Jul 10, 2015 at 14:19
  • check the update that i did in the question
    – gsa
    Commented Jul 10, 2015 at 17:43
  • You update has nothing to do with your original question. Commented Jul 10, 2015 at 17:54
  • Actually it has because it is part of it.I did the the join so far but the new object called "m" is not a SpatialPointsDataFrame, as the "city".and the "city " doesn't have the new column with the population.
    – gsa
    Commented Jul 10, 2015 at 17:58

Joining a shape file with another data frame is convenient using a combination of sf and dplyr:


data(meuse, package = 'sp') # Grab some fake data from package sp
# Convert data from sp to simple feature (sf)
meuse_sf = st_as_sf(meuse, coords = c('x', 'y'), crs = 28992, agr = 'constant')
meuse_sf$ID <- 1:nrow(meuse) # Add ID column/variable

# Create fake data frame with similarly named column/variable ID
df.new <- data.frame(ID=1:nrow(meuse), y=runif(nrow(meuse)))

# Perform left join between simple feature and data frame
meuse <- meuse %>% left_join(df.new, by = 'ID')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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