循环以将新值分配给多个空间数据帧

时间:2015-09-30 15:36:52

标签: r loops spatial assign spatial-data-frame

我在Windows上运行R(V3.2.2)的RStudio(V 0.99.467)工作。我有一个来自ArcGIS的矢量地图集合,我使用rgdal循环读取R来创建类' SpatialPolygonsDataFrame'的对象。

有几个数据QAQC检查和修复我想在同一个循环中执行。例如,我希望从数据框中的条目中删除空格。我可以在循环之外轻松完成此操作,但在循环中使用引用和名称分配很困难。在循环之外,此命令将删除数据中的所有空格:

# the function I want to apply to each map immediately after I read it
as.data.frame(apply(get(mymap)@data[],2,function(x)gsub('\\s+', '',x)))  

此功能也适用于循环,但我无法重新分配新的无空格数据以替换原始数据。下面是一些示例代码,用于显示我正在尝试执行的操作以及我遇到的问题。

# vector of names from map objects
farmnames <- c("Gardner","Mistletoe","Omni","Sturgill")  
library(rgdal)  
# create vector of filenames based on farmnames
filenames <- paste0(farmnames[],"_Farm_Fields_FINAL")  
# loop to read maps and correct data
for (i in 1:length(farmnames)){  
    name <- farmnames[i]  
    assign(name, readOGR(".", filenames[i])) # create map object  
    get(name)@data[]<- as.data.frame(apply(get(name)@data[],2,function(x)gsub('\\s+', '',x))) # remove spaces from map dataframe
}  

但是这最后一行返回错误:&#34; get(name)中的错误@data []&lt; - as.data.frame(apply(get(name)@data [],2,:不能找到函数&#34;得到&lt; - &#34;。我猜我不能在作业的左侧放置一个函数?因为我只是输入&#34; get(name )@data []&#34; R返回正确的答案而没有错误。

我还尝试了各种方法来创建临时数据帧,更改临时数据帧,然后使用assign函数替换地图对象中的数据帧。但同样,这在循环外工作(assign(mymap @ data [],d))而不在循环内(assign(get(name)@data [],d))。

# method 2
d <- as.data.frame(apply(d,2,function(x)gsub('\\s+', '',x)))  
assign(get(name)@data[],d)  

但是这个方法返回错误:&#34;赋值错误(get(name)@data [],d):第一个参数无效&#34;。大概是因为assign中的第一个参数应该是单个元素(变量名),而不是数据帧?

我还创建了一个子循环来迭代遍历变量名称逐列进行更正 - 但是当我可以在主循环中使用单行执行所有更正时,这似乎非常低效 - 如果我可以得到工作任务。我希望有人能够使用上面粘贴的两个例子中的任何一个。

我不确定如何在StackOverflow中为类SpatialPolygonsDataFrame的对象附加示例原始数据。如果这里没有足够的信息来帮助我,我可以在GitHub上创建一个公共文件夹并提供链接吗?但我认为这是一个非常基本的分配问题,因为我对R和编程仍然很陌生。

2 个答案:

答案 0 :(得分:1)

所以这应该(显然确实有效)。

farmnames <- c("Gardner","Mistletoe","Omni","Sturgill")  
for (name in farmnames){ 
  temp <- readOGR(".",paste0(name,"_Farm_Fields_FINAL") )
  temp@data <- as.data.frame(lapply(temp@data,function(x)gsub('\\s+', '',x)))
  assign(name,temp) 
  # rm(temp)
}

请注意,这会在循环的每次迭代中创建一个变量temp,并在末尾创建一个带有相应名称的 new 变量。如果空格有问题,请取消注释最后一行,这会在每一步删除temp变量。

演示:

for (name in farmnames){ 
  temp <- as.data.frame(matrix(paste(LETTERS[1:25],sample(1:25,25)),nc=5))
  temp <- as.data.frame(lapply(temp,function(x)gsub('\\s+', '',x)))
  assign(name,temp) 
  rm(temp)
}
ls()
# [1] "farmnames" "Gardner"   "Mistletoe" "name"      "Omni"      "Sturgill" 

答案 1 :(得分:0)

jhoward的解决方案可能有效,但使用'assign'(和get)通常不是一个好方法。使用列表更清晰,更容易。虽然,由于您没有在循环后指定要对这些对象执行的操作,因此很难确定。我愿意:

farmnames <- c("Gardner", "Mistletoe", "Omni", "Sturgill")  
x <- list()
for (i in 1:length(farmnames)){ 
  temp <- readOGR(".", paste0(farmname[i], "_Farm_Fields_FINAL") )
  temp@data <- as.data.frame(lapply(temp@data,function(x)gsub('\\s+', '',x)))
  x[i] <- temp
}

或者也许使用光栅包中的trim函数来获得更清晰的代码(我假设你所谓的“矢量地图”实际上是shapefile):

library(raster)
farmnames <- c("Gardner", "Mistletoe", "Omni", "Sturgill")  
x <- list()
for (i in 1:length(farmnames)){ 
    filename <- paste0(farmname[i], "_Farm_Fields_FINAL.shp")
    temp <- shapefile(filename)
    temp@data <- trim(temp@data)
    x[i] <- temp
}