合并R中单个数据帧中的多个列

时间:2013-10-30 19:16:39

标签: r

我有一个奇怪的问题,我将几个具有不同物种丰度数据的数据框组合在一起。我使用rbind.fill()来整理数据框,但类似物种的一些列名称拼写略有不同,因此,对于几个物种,我有2-3列。

有没有人知道我可以将这些列中的数据合并在一起的方式?

简单示例:

dat <- matrix(data=c(
    Sp.a=c(1,2,3,4,5,NA,NA,NA,NA,NA), 
    Sp.b=c(3,4,5,6,7,5,4,6,3,4), 
    Sp.c=c(4,4,4,3,2,NA,NA,NA,NA,NA), 
    Spp.A=c(NA,NA,NA,NA,NA,2,3,4,2,3), 
    Spp.C=c(NA,NA,NA,NA,NA,3,4,2,5,4)
    ), 10,5)

colnames(dat)<- c("Sp.a", "Sp.b", "Sp.c", "Spp.A", "Spp.C")

dat
      sp.a  sp.b sp.c Spp.A Spp.C
 [1,]    1    3    4    NA    NA
 [2,]    2    4    4    NA    NA
 [3,]    3    5    4    NA    NA
 [4,]    4    6    3    NA    NA
 [5,]    5    7    2    NA    NA
 [6,]   NA    5   NA     2     3
 [7,]   NA    4   NA     3     4
 [8,]   NA    6   NA     4     2
 [9,]   NA    3   NA     2     5
 [10,]  NA    4   NA     3     4

如何将sp.a和Spp.A合并到一个列中? (sp.c和Spp.C相同)。

感谢您的帮助, 保罗

3 个答案:

答案 0 :(得分:1)

ColsToMerge <- c("sp.a", "Spp.A")
dat[["A.merged"]] <- 
     apply(dat[, ColsToMerge], 1, function(rr) ifelse(is.na(rr[[1]]), rr[[2]], rr[[1]]))

答案 1 :(得分:1)

这是一种方式。这非常普遍,如果你有一个系列分为三列或更多列,它甚至会起作用。

dat <- data.frame(dat)
# get the last letter of each column and make it lowercase, 
# we'll be grouping the columns by this
ns <- tolower(gsub('^.+\\.', '', names(dat)))
# group the columns by their last letter, and run each group through pmax
result <- lapply(split.default(dat, ns), function(x) do.call(function(...) pmax(..., na.rm=TRUE), x))
do.call(cbind, result)
#       a b c
#  [1,] 1 3 4
#  [2,] 2 4 4
#  [3,] 3 5 4
#  [4,] 4 6 3
#  [5,] 5 7 2
#  [6,] 2 5 3
#  [7,] 3 4 4
#  [8,] 4 6 2
#  [9,] 2 3 5
# [10,] 3 4 4

答案 2 :(得分:1)

使用reshape2并使用long - &gt;宽 - &gt;长(再次)格式:

library(reshape2)
## long format
dat.m <- melt(dat)
## remove missing values
dat.m <- dat.m[!is.na(dat.m$value),]
## rename names 
dat.m$Var2 <- tolower(sub("Spp","Sp", dat.m$Var2) )
## wide format
dcast(Var1~Var2,data=dat.m)

   Var1 sp.a sp.b sp.c
1     1    1    3    4
2     2    2    4    4
3     3    3    5    4
4     4    4    6    3
5     5    5    7    2
6     6    2    5    3
7     7    3    4    4
8     8    4    6    2
9     9    2    3    5
10   10    3    4    4