13

ビーガンとggplot2で作成したNMDSプロットの完成に取り組んでいますが、プロットにenvfit種ローディングベクトルを追加する方法がわかりません。私がしようとすると、「無効なグラフィック状態」と表示されます。

以下の例は、別の質問(ビーガンパッケージからのordiellipse関数をggplot2で作成されたNMDSプロットにプロットする)から少し変更されていますが、最初にmetaMDSをggplot2に取り込むためにこの質問を使用したため、含めたい例を正確に表しています。

library(vegan)
library(ggplot2)
data(dune)

# calculate distance for NMDS
NMDS.log<-log(dune+1)
sol <- metaMDS(NMDS.log)

# Create meta data for grouping
MyMeta = data.frame(
  sites = c(2,13,4,16,6,1,8,5,17,15,10,11,9,18,3,20,14,19,12,7),
  amt = c("hi", "hi", "hi", "md", "lo", "hi", "hi", "lo", "md", "md", "lo", 
      "lo", "hi", "lo", "hi", "md", "md", "lo", "hi", "lo"),
row.names = "sites")

# plot NMDS using basic plot function and color points by "amt" from MyMeta
plot(sol$points, col = MyMeta$amt)

# same in ggplot2
NMDS = data.frame(MDS1 = sol$points[,1], MDS2 = sol$points[,2])
ggplot(data = NMDS, aes(MDS1, MDS2)) + 
  geom_point(aes(data = MyMeta, color = MyMeta$amt))

#Add species loadings
vec.sp<-envfit(sol$points, NMDS.log, perm=1000)
plot(vec.sp, p.max=0.1, col="blue")
4

4 に答える 4

11

(そうでなければ優れた)受け入れられた回答の問題、および含まれている図でベクトルがすべて同じ長さである理由を説明する[受け入れられた回答は、回避するために、以下で説明する方法で矢印を拡大縮小するように編集されていることに注意してくださいQ&Aに出くわすユーザーにとっての混乱$vectors$arrows]は、によって返されるオブジェクトのコンポーネントに格納されているenvfit()のは、近似されたベクトルの方向余弦であるということです。これらはすべて単位長であるため、@DidzisElfertsのプロットの矢印はすべて同じ長さです。これはからの出力とは異なりますplot(envfit(sol, NMDS.log))、および順序構成(「軸」)との相関によってベクトル矢印座標をスケーリングするために発生します。そうすれば、叙階構成との弱い関係を示す種は、より短い矢印を取得します。スケーリングは、方向余弦に、印刷出力の表に示されている値sqrt(r2)を掛けることによって行われます。ビーガンは、既存のプロットにベクトルを追加r2するときに、矢印の相対的な長さを維持しながら、使用可能なプロットスペースを満たすようにベクトルのセットをスケーリングしようとします。これがどのように行われるかについては、の「詳細」セクションで説明されており、エクスポートされていない関数を使用する必要があります。?envfitvegan:::ordiArrowMul(result_of_envfit)

これは、 ggplot2plot.envfitを使用する動作を複製する完全に機能する例です。

library(vegan)
library(ggplot2)
library(grid)
data(dune)

# calculate distance for NMDS
NMDS.log<-log1p(dune)
set.seed(42)
sol <- metaMDS(NMDS.log)

scrs <- as.data.frame(scores(sol, display = "sites"))
scrs <- cbind(scrs, Group = c("hi","hi","hi","md","lo","hi","hi","lo","md","md",
                              "lo","lo","hi","lo","hi","md","md","lo","hi","lo"))

set.seed(123)
vf <- envfit(sol, NMDS.log, perm = 999)

この時点で停止して見てみるとvf

> vf

***VECTORS

             NMDS1       NMDS2     r2 Pr(>r)    
Belper -0.78061195 -0.62501598 0.1942  0.174    
Empnig -0.01315693  0.99991344 0.2501  0.054 .  
Junbuf  0.22941001 -0.97332987 0.1397  0.293    
Junart  0.99999981 -0.00062172 0.3647  0.022 *  
Airpra -0.20995196  0.97771170 0.5376  0.002 ** 
Elepal  0.98959723  0.14386566 0.6634  0.001 ***
Rumace -0.87985767 -0.47523728 0.0948  0.429
.... <truncated>

したがって、r2データは列NMDS1との値をスケーリングするために使用されますNMDS2。最終的なプロットは次のように作成されます。

spp.scrs <- as.data.frame(scores(vf, display = "vectors"))
spp.scrs <- cbind(spp.scrs, Species = rownames(spp.scrs))

p <- ggplot(scrs) +
  geom_point(mapping = aes(x = NMDS1, y = NMDS2, colour = Group)) +
  coord_fixed() + ## need aspect ratio of 1!
  geom_segment(data = spp.scrs,
               aes(x = 0, xend = NMDS1, y = 0, yend = NMDS2),
               arrow = arrow(length = unit(0.25, "cm")), colour = "grey") +
  geom_text(data = spp.scrs, aes(x = NMDS1, y = NMDS2, label = Species),
            size = 3)

これにより、次のものが生成されます。

ここに画像の説明を入力してください

于 2013-05-10T15:38:25.300 に答える
7

ライブラリの追加から始めます。さらに、ライブラリgridが必要です。

library(ggplot2)
library(vegan)
library(grid)
data(dune)

metaMDS分析を行い、結果をデータフレームに保存します。

NMDS.log<-log(dune+1)
sol <- metaMDS(NMDS.log)

NMDS = data.frame(MDS1 = sol$points[,1], MDS2 = sol$points[,2])

種の負荷を追加し、データフレームとして保存します。矢印の余弦定理の方向は、リストvectorsと行列に格納されますarrowsr2矢印の座標を取得するには、これらの方向の値に、に格納されている値の平方根を掛ける必要がありますvectors$rscores()より簡単な方法は、@GavinSimpsonの回答で提供されている関数を使用することです。次に、名前を含む新しい列を追加しspeciesます。

vec.sp<-envfit(sol$points, NMDS.log, perm=1000)
vec.sp.df<-as.data.frame(vec.sp$vectors$arrows*sqrt(vec.sp$vectors$r))
vec.sp.df$species<-rownames(vec.sp.df)

矢印が追加されgeom_segment()、種名が。で追加されgeom_text()ます。両方のタスクでデータフレームvec.sp.dfが使用されます。

ggplot(data = NMDS, aes(MDS1, MDS2)) + 
  geom_point(aes(data = MyMeta, color = MyMeta$amt))+
  geom_segment(data=vec.sp.df,aes(x=0,xend=MDS1,y=0,yend=MDS2),
      arrow = arrow(length = unit(0.5, "cm")),colour="grey",inherit_aes=FALSE) + 
  geom_text(data=vec.sp.df,aes(x=MDS1,y=MDS2,label=species),size=5)+
  coord_fixed()

ここに画像の説明を入力してください

于 2013-02-05T16:35:08.877 に答える
3

遅れて追加してもいいですか?

Envfitはpvalueを提供し、重要なパラメーターをプロットしたい場合もあります(plotコマンドでp。= 0.05を使用してビーガンが実行できること)。私はggplot2でそれを行うのに苦労しました。これが私の解決策です、多分あなたはもっとエレガントなものを見つけますか?

上からのDidzisの答えから始めて:

ef<-envfit(sol$points, NMDS.log, perm=1000)
ef.df<-as.data.frame(ef$vectors$arrows*sqrt(ef$vectors$r))
ef.df$species<-rownames(ef.df)

#only significant pvalues
#shortcutting ef$vectors
A <- as.list(ef$vectors)
#creating the dataframe
pvals<-as.data.frame(A$pvals)
arrows<-as.data.frame(A$arrows*sqrt(A$r))
C<-cbind(arrows, pvals)
#subset
Cred<-subset(C,pvals<0.05)
Cred <- cbind(Cred, Species = rownames(Cred))

上記のように、「Cred」をgeom_segment-argumentに実装できるようになりました。

于 2014-08-21T11:31:31.080 に答える
1

簡単な追加:別名「矢印の長さはプロット領域を最大限に活用する」plot.envfit内の機能の完全な表現を取得するには、係数を適用する必要があります。ggplot2それがギャビンによって具体的に言及されたので、それが上記の答えで意図的に省略されたかどうかはわかりませんか?を使用して必要なスケーリング係数を抽出するだけで、のarrow_factor <- ordiArrowMul(vf)両方のNMDS列に適用するか、次のspp.scrsように手動で行うことができます。

arrow_factor <- ordiArrowMul(vf)
spp.scrs <- as.data.frame(scores(vf, display = "vectors")) * arrow_factor
spp.scrs <- cbind(spp.scrs, Species = rownames(spp.scrs), Pvalues = vf$vectors$pvals, R_squared = vf$vectors$r)

# select significance similarly to `plot(vf, p.max = 0.01)`
spp.scrs <- subset(spp.scrs, Pvalues < 0.01)

# you can also add the arrow factor in here (don't do both!)
ggplot(scrs) +
  geom_point(mapping = aes(x = NMDS1, y = NMDS2, colour = Group)) +
  coord_fixed() + ## need aspect ratio of 1!
  geom_segment(data = spp.scrs,
               aes(x = 0, xend = NMDS1 * arrow_factor, y = 0, yend = NMDS2 * arrow_factor),
               arrow = arrow(length = unit(0.25, "cm")), colour = "grey") +
  geom_text(data = spp.scrs, aes(x = NMDS1 * arrow_factor, y = NMDS2 * arrow_factor, label = Species),
            size = 3)
于 2020-05-20T12:00:30.487 に答える