我有一堆栅格(每个物种一个),然后我有一个数据框,其中包含纬度/长列以及物种名称。
fls = list.files(pattern="median")
s <- stack(fls)
df<-c("x","y","species name")
我希望能够一次只选择一个栅格以使用提取功能。我希望选择基于物种名称列的部分匹配。我想这样做是因为栅格名称可能与物种列表中的名称不完全匹配,可能存在大写不匹配或栅格图层名称可能更长,例如“species_name_median”,或者可能还有“ _“而不是空白。
for(i:length(df.species name))
{
result<-extract(s[[partial match to "species name[i]" ]],df.xy)
}
我希望这是有意义的,我只想一次使用一个栅格进行提取。我可以使用s [[i]]轻松选择单个栅格,但不能保证列表中的每个物种都有其等效的栅格。
答案 0 :(得分:4)
如果要查询的点数据包含x和y坐标的data.frame以及要查询的图层的相应物种名称,则可以使用这两个命令执行所有操作:
# Find the layer to match on using 'grepl' and 'which' converting all names to lowercase for consistency
df$layer <- lapply( df$species , function(x) which( grepl( tolower(x) , tolower(names(s)) ) ) )
# Extract each value from the appropriate layer in the stack
df$Value <- sapply( seq_len(nrow(df)) , function(x) extract( s[[ df$layer[x] ]] , df[ x , 1:2 ] ) )
从第一行开始:
df$layer
,它将成为我们需要用于该行的堆栈中rasterLayer
的索引。lapply
遍历列df$species
中的所有元素,并依次使用df$species
中的每个项作为输入变量x
应用匿名函数。 lapply
是一个循环结构,即使它看起来不像一个。df$species
的第一个元素,现在是x
并在grepl
中使用它(意味着类似'全局常规模式匹配逻辑')来查找哪个我们的堆栈s
的名称元素包含我们的物种模式。我们在模式上使用tolower()
来匹配(x
)和要匹配的元素(names(s)
),以确保我们匹配即使案例与案例不匹配,例如"Tiger"
找不到"tiger"
。grepl
返回一个逻辑向量,其中找到的元素与模式匹配,例如grepl( "abc" , c("xyz", "wxy" , "acb" , "zxabcty" ) )
返回F , F , T , T
。我们使用which
来获取这些元素的索引。TRUE
索引将是我们想要的堆栈中的层的索引在第二行,sapply
:
sapply
是一个非常类似lapply
的迭代器,但它返回一个向量而不是值列表。你可以在这个用例中使用TBH。1
到nrow(df)
的一系列数字。x
"x"
给出)提取"y"
和x
坐标(分别为第1列和第2列),使用我们进入了上一行。x/y
坐标的提取值我希望有所帮助!!
一些有关数据的实例:
require( raster )
# Sample rasters - note the scale of values in each layer
# Tens
r1 <- raster( matrix( sample(1:10,100,repl=TRUE) , ncol = 10 ) )
# Hundreds
r2 <- raster( matrix( sample(1e2:1.1e2,100,repl=TRUE) , ncol = 10 ) )
# Thousands
r3 <- raster( matrix( sample(1e3:1.1e3,100,repl=TRUE) , ncol = 10 ) )
# Stack the rasters
s <- stack( r1,r2,r3 )
# Name the layers in the stack
names(s) <- c("LIon_medIan" , "PANTHeR_MEAN_AVG" , "tiger.Mean.JULY_2012")
# Data of points to query on
df <- data.frame( x = runif(10) , y = runif(10) , species = sample( c("lion" , "panther" , "Tiger" ) , 10 , repl = TRUE ) )
# Run the previous code
df$layer <- lapply( df$species , function(x) which( grepl( tolower(x) , tolower(names(s)) ) ) )
df$Value <- sapply( seq_len(nrow(df)) , function(x) extract( s[[ df$layer[x] ]] , df[ x , 1:2 ] ) )
# And the result (note the scale of Values is consistent with the scale of values in each rasterLayer in the stack)
df
# x y species layer Value
#1 0.4827577 0.7517476 lion 1 1
#2 0.8590993 0.9929104 lion 1 3
#3 0.8987446 0.4465397 tiger 3 1084
#4 0.5935572 0.6591223 panther 2 107
#5 0.6382287 0.1579990 panther 2 103
#6 0.7957626 0.7931233 lion 1 4
#7 0.2836228 0.3689158 tiger 3 1076
#8 0.5213569 0.7156062 lion 1 3
#9 0.6828245 0.1352709 panther 2 103
#10 0.7030304 0.8049597 panther 2 105
答案 1 :(得分:0)
你试过subset
你的RasterStack吗?
像这样的东西
for(i in 1: length(df.species.name)) #assuming it is the 'partial species name'
{
result <- subset(s, grep(df.species.name[i], ignore.case = TRUE, value = TRUE)
}
了解不同的栅格和物种名称可能会很有趣。这将允许更好的方法,必要时调整正则表达式。你会在这里找到很多关于grep的引用。也请尝试?grep
。