অভিন্ন বহুভুজ আইডি সহ স্পেশালপলিগনস ডেটা ফ্রেমগুলি রিবাইন্ড করার সঠিক উপায়?


22

আইডিগুলি ওভারল্যাপ হয়ে গেলে এসপিডিএফগুলিকে একসাথে রাখার জন্য উপযুক্ত আর আইডিয়মটি কী? মনে রাখবেন যে এখানে (যেমন প্রায়ই হয়) আইডিগুলি মূলত অর্থহীন তাই এটি খুব বিরক্তিকর যে আমি কেবল rbind এড়াতে পারি না ...

library(sp)
library(UScensus2000)
library(UScensus2000tract)

data(state) # for state names
states <- gsub( " ", "_", tolower(state.name) )
datanames <- paste(states,"tract", sep=".")
data( list=datanames )
lst <- lapply(datanames,get)

nation <- do.call( rbind, lst )
Error in validObject(res) : 
  invalid class SpatialPolygons object: non-unique Polygons ID slot values

# This non-exported function designed to solve this doesn't seem to work any more.
d <- sp:::makeUniqueIDs( list(arizona.tract,delaware.tract) )
Error in slot(i, "ID") : 
  no slot of name "ID" for this object of class "SpatialPolygonsDataFrame"

উত্তর:


15

আইডি, স্লট এবং প্রয়োগ ধরণের ফাংশন। আমার শীর্ষস্থানীয় তিনটি প্রিয় জিনিস যা আমি যা করি তার জন্য একেবারে প্রয়োজনীয়। আমি ভেবেছিলাম যে আমি এই বিষয়ে আরও কন্টেন্ট তৈরি করতে সাড়া দেব।

নীচের কোডটি কাজ করে তবে এটি "অকেজো" আইডি মান ধরে রাখে। আরও ভাল কোড জিনিসগুলি বিশ্লেষণে সময় নিতে পারে যাতে প্রতিটি ট্র্যাক্টের আইডি হিসাবে রাজ্য FIPS, কাউন্টি FIPS, এবং ট্র্যাক্টের ঠিকানা থাকে। এটি হওয়ার জন্য আরও কয়েকটি লাইন, তবে যেহেতু আপনি আইডির বিষয়ে চিন্তা করেন না আমরা এখনই তা ছেড়ে দেব।

#Your Original Code
library(sp)
library(UScensus2000)
library(UScensus2000tract)

data(state) # for state names
states <- gsub( " ", "_", tolower(state.name) )
datanames <- paste(states,"tract", sep=".")
data( list=datanames )
lst <- lapply(datanames,get)

#All good up to here, but we need to create unique ID's before rbind

#Modified from Roger Bivand's response at:
# https://stat.ethz.ch/pipermail/r-sig-geo/2007-October/002701.html

#For posterity: We can access the ID in two ways:
class(alaska.tract)
getSlots(class(alaska.tract))
class(slot(alaska.tract, "polygons")[[1]])
getSlots(class(slot(alaska.tract, "polygons")[[1]]))

#So to get all ID's
sapply(slot(alaska.tract, "polygons"), function(x) slot(x, "ID"))
#or
rownames(as(alaska.tract, "data.frame"))
#These should be the same, but they are quite different...sigh. Doesn't matter for
#what follows though

#To make them uniform we can write a function using the spChFIDs function from sp:
makeUniform<-function(SPDF){
  pref<-substitute(SPDF)  #just putting the file name in front.
  newSPDF<-spChFIDs(SPDF,as.character(paste(pref,rownames(as(SPDF,"data.frame")),sep="_")))
  return(newSPDF)
}

#now to do this for all of our state files
newIDs<-lapply(lst,function(x) makeUniform(x))

#back to your code...
nation <- do.call( rbind, newIDs )

ধন্যবাদ। আমি এখন কয়েক দিন ধরে এটি পরীক্ষা করার অর্থ করছি তবে জীবন হস্তক্ষেপ করেছে। আমি এক ধরনের বিস্মিত এটি কোডের এই অনেক লাইন। আপনি কি মনে rbindকরেন যে spপ্যাকেজের এসপিডিএফ পদ্ধতিতে কোনও প্যাচ জমা দেওয়ার উপযুক্ত হবে ? আমি এই ,deduplicateIDs=TRUE
এরি বি ফ্রেডম্যান

কার্যকারিতাটির জন্য কোডটির কেবলমাত্র তিনটি লাইন এবং একটি এটি প্রাক-রিবাইন্ড প্রয়োগ করার জন্য, তবে এটি আপনার সমস্যার জন্য প্রক্রিয়া করতে কিছুটা সময় নেয় না। আমি সবসময় এসপিডিএফ-এর আইডি হ্যান্ডলিংয়ের সমস্যা হিসাবে খুঁজে পেয়েছি (যে কোনও সময় আমি উদাহরণস্বরূপ আরজিডাল দিয়ে কিছু লোড করি) তবে রজার বিভান্ড সর্বদা তাদের আচরণ করতে সক্ষম বলে মনে হয় তাই আমি কেবল ধরে নিয়েছি এটি আমার নিজের ঘাটতি। আমি প্যাচটির ধারণাটি পছন্দ করি তবে অবাক হয়ে যায় যে যদি এই স্লটগুলিতে অ্যাক্সেস করা এসপিতে অন্য জিনিসগুলির জন্য জটিলতা সৃষ্টি করে।
csfowler

দুর্দান্ত উত্তর। অন্যের কাছে কেবল উপদেশের একটি শব্দ যুক্ত করতে চাই যে যখন আমার কোডটিতে রাইবাইন্ড আটকে যায় তখন এটি সাধারণত পূর্ববর্তী একটি ভুলের কারণে হয় (ফলস্বরূপ আইডি তৈরি করে)। সুতরাং ত্রুটিটি সঠিক।
ক্রিস

20

এটি একটি আরও সহজ পদ্ধতির:

x <- rbind(x1, x2, x3, makeUniqueIDs = TRUE)  

1
আমি আশা করি এটি rbind সহায়তা পৃষ্ঠাতে নথিভুক্ত করা হয়েছিল। আমাকে এই তর্কটির জন্য তারা ব্যবহৃত কেসিং বিধিগুলি মনে করতে পারছি না প্রতিবারই আমাকে এখানে দেখতে হবে। অবশ্যই সেরা উত্তর। আমি মনে করি না এটির আরও প্রসঙ্গে প্রয়োজন, এবং অবশ্যই অপসারণ করা উচিত নয়!
JMT2080AD

ডকুমেন্টেশন "Make.row.names = TRUE)" এর পরামর্শ দেয় ... যা কাজ করছে বলে মনে হয় না। উদাহরণটি অনুলিপি-পেস্ট করুন।
মোক্স

আমি মনে করি সাহায্যে এটি নথিবদ্ধ না হওয়ার কারণ হ'ল আপনি যখন কোনও এসপি অবজেক্টকে আরবাইন্ডে পাস করেন আপনি একটি এসপি পদ্ধতি কল করছেন। দেখুন methods(class = "SpatialLines")। আমি এটি সম্পর্কে নিশ্চিত নই তবে এটি এখনই আমার সেরা অনুমান। আমি বেশ নিশ্চিত এডজার এবং কো। আরবিন্ড নিজেই রক্ষণ করছেন না, তাই আরবাইন্ডে ডকুমেন্টেশনের অভাব।
JMT2080AD

( x1, x2, x3, ..., xn) একত্রীকরণের জন্য অবজেক্টের দীর্ঘ তালিকা থাকলে কী হবে ? সমস্ত তালিকা টাইপ না করে পুরো তালিকাটি ক্যাপচার করার কোনও পদ্ধতি আছে?
ফিলি

কলামগুলির সংখ্যা সমান হলে কেবল কাজ করে।
ডেনিস

9

ঠিক আছে, এখানে আমার সমাধান। পরামর্শ স্বাগত জানাই। আমি সম্ভবত এটি কোনও প্যাচ হিসাবে জমা দিচ্ছি spযদি না কেউ যদি কোন উজ্জ্বল ভুল দেখায়।

#' Get sp feature IDs
#' @aliases IDs IDs.default IDs.SpatialPolygonsDataFrame
#' @param x The object to get the IDs from
#' @param \dots Pass-alongs
#' @rdname IDs
IDs <- function(x,...) {
  UseMethod("IDs",x)
}
#' @method IDs default
#' @S3method IDs default
#' @rdname IDs
IDs.default <- function(x,...) {
  stop("Currently only SpatialPolygonsDataFrames are supported.")
}
#' @method IDs SpatialPolygonsDataFrame
#' @S3method IDs SpatialPolygonsDataFrame
#' @rdname IDs
IDs.SpatialPolygonsDataFrame <- function(x,...) {
  vapply(slot(x, "polygons"), function(x) slot(x, "ID"), "")
}

#' Assign sp feature IDs
#' @aliases IDs<- IDs.default<-
#' @param x The object to assign to
#' @param value The character vector to assign to the IDs
#' @rdname IDs<-
"IDs<-" <- function( x, value ) {
  UseMethod("IDs<-",x)
}
#' @method IDs<- SpatialPolygonsDataFrame
#' @S3method IDs<- SpatialPolygonsDataFrame
#' @rdname IDs<-
"IDs<-.SpatialPolygonsDataFrame" <- function( x, value) {
  spChFIDs(x,value)
}

#' rbind SpatialPolygonsDataFrames together, fixing IDs if duplicated
#' @param \dots SpatialPolygonsDataFrame(s) to rbind together
#' @param fix.duplicated.IDs Whether to de-duplicate polygon IDs or not
#' @return SpatialPolygonsDataFrame
#' @author Ari B. Friedman, with key functionality by csfowler on StackExchange
#' @method rbind.SpatialPolygonsDataFrame
#' @export rbind.SpatialPolygonsDataFrame
rbind.SpatialPolygonsDataFrame <- function(..., fix.duplicated.IDs=TRUE) {
  dots <- as.list(substitute(list(...)))[-1L]
  dots_names <- as.character(dots) # store names of objects passed in to ... so that we can use them to create unique IDs later on
  dots <- lapply(dots,eval)
  names(dots) <- NULL
  # Check IDs for duplicates and fix if indicated
  IDs_list <- lapply(dots,IDs)
  dups.sel <- duplicated(unlist(IDs_list))
  if( any(dups.sel) ) {
    if(fix.duplicated.IDs) {
      dups <- unique(unlist(IDs_list)[dups.sel])
      # Function that takes a SPDF, a string to prepend to the badID, and a character vector of bad IDs
      fixIDs <- function( x, prefix, badIDs ) {
        sel <-  IDs(x) %in% badIDs
        IDs(x)[sel] <- paste( prefix, IDs(x)[sel], sep="." )
        x
      }
      dots <- mapply(FUN=fixIDs , dots, dots_names, MoreArgs=list(badIDs=dups) )
    } else {
      stop("There are duplicated IDs, and fix.duplicated.IDs is not TRUE.")
    }
  }
  # One call to bind them all
  pl = do.call("rbind", lapply(dots, function(x) as(x, "SpatialPolygons")))
  df = do.call("rbind", lapply(dots, function(x) x@data))
  SpatialPolygonsDataFrame(pl, df)
}

1

আমি এখানে অন্যান্য উত্তরগুলির বিশদ প্রশংসা করেছি এবং সেগুলি তৈরি করে, আমি যে ওয়ান লাইনারটি এসেছি সেগুলি নীচে রয়েছে। ওপির মতো, আমি আইডির অর্থ সম্পর্কে খুব বেশি যত্ন নিই না, তবে নিম্নলিখিতগুলি আরও তথ্যমূলক আইডি এম্বেড করার জন্যও রূপান্তর করতে পারে।

lst <- lapply(1:length(lst), function(i) spChFIDs(lst[[i]], paste0(as.character(i), '.', 1:length(lst[[i]]))))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.