0

我在 Windows10 上运行 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
}  

但是最后一行返回错误:“get(name)@data[] <- as.data.frame(apply(get(name)@data[], 2,: could not find function "get<-" . 我猜我不能把函数放在赋值的左边?因为如果我只输入“get(name)@data[]”,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)  

但是此方法返回错误:“assign(get(name)@data[], d) 中的错误:第一个参数无效”。大概是因为 assign 中的第一个参数应该是单个元素(变量名),而不是数据框?

我还创建了一个子循环来遍历变量名称,逐列进行更正 - 但是当我可以在主循环中使用一行执行所有更正时,这似乎非常低效 - 如果我可以让分配工作。我希望有人有使用我上面粘贴的两个示例中的任何一个的解决方案。

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

4

2 回答 2

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在循环的每次迭代中创建一个变量,并在最后创建一个具有适当名称的新变量。如果空间是一个问题,请取消注释最后一行,这会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" 
于 2015-10-01T15:23:06.613 回答
0

jhoward 的解决方案可能有效,但使用“分配”(和获取)通常不是一个好方法。使用列表更清晰、更容易。虽然,由于您没有指定在循环之后要对这些对象做什么,因此很难确定。我会做:

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
}

或者也许使用 raster 包中的 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
}
于 2015-10-02T05:17:55.620 回答