我在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和编程仍然很陌生。
答案 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
}