如果你需要查询的点的数据是一个包含x和y坐标以及相应物种名称的数据框,那么你可以使用以下两个命令完成全部操作:
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 ] ) )
工作原理
从第一行开始:
- 首先,我们定义一个新的列向量
df$layer
,它将是我们需要在该行中使用的rasterLayer
在堆栈中的索引。
lapply
沿着列df$species
中的所有元素迭代,并使用每个df$species
中的项依次作为输入变量x
应用匿名函数。尽管它看起来不像,但lapply
是一个循环结构。
- 在第一次迭代中,我们取
df$species
的第一个元素,即现在的x
,并在s
的名称中使用grepl
(意思是“全局正则模式匹配逻辑”)查找包含我们物种模式的元素。我们对要匹配的模式(x
)和要匹配的元素(names(s)
)都使用tolower()
以确保即使大小写不匹配时也能匹配,例如"Tiger"
将无法找到"tiger"
。
grepl
返回一个逻辑向量,其中包含它找到模式匹配的元素,例如grepl("abc", c("xyz", "wxy", "acb", "zxabcty"))
返回F, F, T, T
。我们使用which
来获取这些元素的索引。
- 我们的想法是为每一行获取一个且仅一个堆栈中与物种名称匹配的层,因此唯一的
TRUE
索引将是我们想要的堆栈中的层的索引。
在第二行,sapply
:
sapply
是一个迭代器,与lapply
非常相似,但它返回一个向量而不是值列表。在这个用例中,你可以使用任何一个。
- 现在,我们沿着从
1
到nrow(df)
的数字序列进行迭代。
- 我们在另一个匿名函数中使用行号作为输入变量
x
- 我们想提取数据框的当前行(由
x
给出)的"x"
和"y"
坐标(分别为第1列和第2列),使用我们在上一行得到的层。
- 我们将所有这些操作的结果分配给数据框中的另一列,该列包含适当层的
x/y
坐标的提取值
我希望这有所帮助!
以下是一些数据的示例:
require( raster )
r1 <- raster( matrix( sample(1:10,100,repl=TRUE) , ncol = 10 ) )
r2 <- raster( matrix( sample(1e2:1.1e2,100,repl=TRUE) , ncol = 10 ) )
r3 <- raster( matrix( sample(1e3:1.1e3,100,repl=TRUE) , ncol = 10 ) )
s <- stack( r1,r2,r3 )
names(s) <- c("LIon_medIan" , "PANTHeR_MEAN_AVG" , "tiger.Mean.JULY_2012")
df <- data.frame( x = runif(10) , y = runif(10) , species = sample( c("lion" , "panther" , "Tiger" ) , 10 , repl = TRUE ) )
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 ] ) )
df