eug*_*ego 11 merge aggregate r dataframe
我有3个数据框(行:站点,列:物种名称)的站点内的物种丰富度.行号相同,但列号不同,因为并非所有物种都在所有三个数据帧中.我想将它们合并到一个数据框架中,总结出相同物种的丰富程度.例如:
data.frame1
Sp1 Sp2 Sp3 Sp4
site1 1 2 3 1
site2 0 2 0 1
site3 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
data.frame2
Sp1 Sp2 Sp4
site1 0 1 2
site2 1 2 0
site3 1 1 1
Run Code Online (Sandbox Code Playgroud)
data.frame3
Sp1 Sp2 Sp5 Sp6
site1 0 1 1 1
site2 1 1 1 5
site3 2 0 0 0
Run Code Online (Sandbox Code Playgroud)
我想拥有的是:
Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
site1 1 4 3 3 1 1
site2 2 5 0 1 1 5
site3 4 2 1 2 0 0
Run Code Online (Sandbox Code Playgroud)
我想我必须使用合并,但到目前为止,我的尝试未能得到我想要的东西.
任何帮助表示赞赏.
Aru*_*run 21
我用plyr的rbind.fill是这样的:
pp <- cbind(names=c(rownames(df1), rownames(df2), rownames(df3)),
rbind.fill(list(df1, df2, df3)))
# names Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
# 1 site1 1 2 3 1 NA NA
# 2 site2 0 2 0 1 NA NA
# 3 site3 1 1 1 1 NA NA
# 4 site1 0 1 NA 2 NA NA
# 5 site2 1 2 NA 0 NA NA
# 6 site3 1 1 NA 1 NA NA
# 7 site1 0 1 NA NA 1 1
# 8 site2 1 1 NA NA 1 5
# 9 site3 2 0 NA NA 0 0
Run Code Online (Sandbox Code Playgroud)
然后,汇总plyr's ddply如下:
ddply(pp, .(names), function(x) colSums(x[,-1], na.rm = TRUE))
# names Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
# 1 site1 1 4 3 3 1 1
# 2 site2 2 5 0 1 1 5
# 3 site3 4 2 1 2 0 0
Run Code Online (Sandbox Code Playgroud)
另一种替代方法是使用melt/cast来自reshape2.这是一个简单的例子:
df1 <- read.table(header=T, text="
Sp1 Sp2 Sp3 Sp4
site1 1 2 3 1
site2 0 2 0 1
site3 1 1 1 1")
df2 <- read.table(header=T, text="
Sp1 Sp2 Sp4
site1 0 1 2
site2 1 2 0
site3 1 1 1")
df3 <- read.table(header=T, text="
Sp1 Sp2 Sp5 Sp6
site1 0 1 1 1
site2 1 1 1 5
site3 2 0 0 0")
df1$site <- rownames(df1)
df2$site <- rownames(df2)
df3$site <- rownames(df3)
DF <- rbind(melt(df1,id="site"),melt(df2,id="site"),melt(df3,id="site"))
dcast(data=DF,formula=site ~ variable,fun.aggregate=sum)
site Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
1 site1 1 4 3 3 1 1
2 site2 2 5 0 1 1 5
3 site3 4 2 1 2 0 0
Run Code Online (Sandbox Code Playgroud)
简而言之,我们使用站点指定作为附加变量,并将每个数据帧转换为长格式,然后将它们连接成单个数据帧.后者包含长格式的所有值.随着dcast我们创建所需的数据帧,点行是(公式的左边),变量列是(公式右侧).sum函数用于生成多个单元格的变量.
当然,代码可以通过循环或*apply函数扩展到更一般的情况.
添加到可用的选项,这里还有两个坚持基础R.
第一种选择:广泛聚合(有点)
temp <- cbind(df1, df2, df3)
temp
# Sp1 Sp2 Sp3 Sp4 Sp1 Sp2 Sp4 Sp1 Sp2 Sp5 Sp6
# site1 1 2 3 1 0 1 2 0 1 1 1
# site2 0 2 0 1 1 2 0 1 1 1 5
# site3 1 1 1 1 1 1 1 2 0 0 0
sapply(unique(colnames(temp)),
function(x) rowSums(temp[, colnames(temp) == x, drop = FALSE]))
# Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
# site1 1 4 3 3 1 1
# site2 2 5 0 1 1 5
# site3 4 2 1 2 0 0
Run Code Online (Sandbox Code Playgroud)
第二种选择:半宽到长到宽
从概念上讲,这与Maxim类似.K的答案:以长格式获取数据,这使得操作更容易:
> temp1 <- t(cbind(df1, df2, df3))
> # You'll get a warning in the next step
> # Safe to ignore though...
> temp2 <- data.frame(var = rownames(temp), stack(data.frame(temp)))
Warning message:
In data.row.names(row.names, rowsi, i) :
some row.names duplicated: 5,6,7,8,9 --> row.names NOT used
> xtabs(values ~ ind + var, temp2)
var
ind Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
site1 1 4 3 3 1 1
site2 2 5 0 1 1 5
site3 4 2 1 2 0 0
Run Code Online (Sandbox Code Playgroud)