R:使用许多配对物种和丰富列重新组织数据框

时间:2016-02-10 19:59:58

标签: r

我获得了生态数据的数据框架,其中包含几个物种丰富的成对列,如下所示:

df <- data.frame(site = 1:3,
                 sp1 = c("A","A","X"), abund1 = c(10,20,30),
                 sp2 = c("B","B","Y"), abund2 = c(10,20,30),
                 sp3 = c("C","Y","Z"), abund3 = c(10,20,30))

   site sp1 abund1 sp2 abund2 sp3 abund3
1     1   A     10   B     10   C     10
2     2   A     20   B     20   Y     20
3     3   X     30   Y     30   Z     30

(我正在使用的实际数据有6对物种和丰度列)

我需要将其纳入网站与物种格式以进行任何进一步分析,如下所示:

    site   A    B    C    X    Y    Z
1      1  10   10   10    0    0    0
2      2  20   20    0    0   20    0
3      3   0    0    0   30   30   30

我唯一能想到的就是首先将其转换为3列数据框,其中包含列&#34; site&#34;,&#34; species&#34;和&#34;丰度&#34 ;,然后使用reshape包。为此,我考虑使用for循环遍历原始数据帧的每一行,将每一行转换为新的数据帧,然后使用rbind将它们全部重新组合在一起。但它似乎非常笨重,我想知道是否有人可以建议更好的方式?

2 个答案:

答案 0 :(得分:3)

我们可以尝试从recast reshape2首先融合数据框然后再展开。使用measure.var=c(2,4,6)标识正确的标签列。 recast能够通过将id.varmeasure.var发送到melt然后将所有其他参数发送到dcast来结合这两个功能:

library(reshape2)
recast(df, id.var="site",measure.var=c(2,4,6), site~value,value.var="site",fill=0)
#   site A B C X Y Z
# 1    1 1 1 1 0 0 0
# 2    2 2 2 0 0 2 0
# 3    3 0 0 0 3 3 3

<强>更新

使用新数据:

s <- stack(df[-1])
newdf <- cbind(site=df[,1],as.data.frame(lapply(split(s, as.numeric(grepl("sp", s$ind))),'[',1)))
dcast(newdf, site~values.1, fill=0, value.var="values")
#   site  A  B  C  X  Y  Z
# 1    1 10 10 10  0  0  0
# 2    2 20 20  0  0 20  0
# 3    3  0  0  0 30 30 30

甚至:

x1 <- unlist(df[-1][c(T,F)], use.names=F)
x2 <- unlist(df[-1][c(F,T)], use.names=F)
df2 <- cbind.data.frame(site=df$site,x1,x2)
dcast(df2, site~x1, fill=0, value.var="x2")

这也应该有效:

m1 <- melt(df, id.var="site", measure.var=c(2,4,6))
m2 <- melt(df, id.var="site", measure.var=c(3,5,7))
m3 <- merge(m1, m2, by=1)[c(T,F)]
dcast(m3[!duplicated(m3[1:2]),], site~value.x, fill=0, value.var="value.y")

答案 1 :(得分:1)

考虑列绑定多个reshape2 dcasts,然后选择最终列:

library(reshape2)

reshapedf <- cbind(dcast(df[c('site', 'sp1', 'abund1')],
                         site~sp1, sum, value.var="abund1"),
                   dcast(df[c('site', 'sp2', 'abund2')],
                         site~sp2, sum, value.var="abund2"),
                   dcast(df[c('site', 'sp3', 'abund3')],
                         site~sp3, sum, value.var="abund3"))

reshapedf <- reshapedf[c('site','A','B','C','X','Y','Z')]

#   site    A   B   C   X   Y   Z
#1  1       10  10  10  0   0   0
#2  2       20  20  0   0   0   0
#3  3       0   0   0   30  30  30