简化数据框中数据的方法

时间:2014-06-14 08:37:06

标签: r dataframe row simplify

我有一组处理蛋白质序列的15个数据框,我的目标是分析蛋白质随时间的变化。但是,我的数据框架有大约5000个基因。所以我正在寻找一种简化数据的方法,以便于分析。

以下是示例数据框。

> sample
  p1 p2 p3 year
1  a  d  d 1970
2  a  c  e 1970
3  b  d  e 1970
4  b  c  d 1985
5  b  c  d 1985
6  b  c  d 1999

我想要做的是每年分析每个职位(p1 p2p3),并返回该年度该职位的最常见职位,从而创建新数据框架每年只有一个序列。结果数据框应如下所示:

> result
  p1 p2 p3 year
1  a  d  e 1970
2  b  c  d 1985
3  b  c  d 1999

数据框已按日期排序,但我不知道每年有多少条目。那么,有没有办法用这种方法简化我的数据?

3 个答案:

答案 0 :(得分:5)

data.table解决方案:

dat <- read.table(text=' p1 p2 p3 year
1  a  d  d 1970
2  a  c  e 1970
3  b  d  e 1970
4  b  c  d 1985
5  b  c  d 1985
6  b  c  d 1999',header=TRUE)

library(data.table)
DT <- as.data.table(dat)

DT[,lapply(.SD,function(x){ y = table(x)
                            names(y)[which.max(y)]}),
   year]

#      year p1 p2 p3
#  1: 1970  a  d  e
#  2: 1985  b  c  d
#  3: 1999  b  c  d

编辑另一个Base R解决方案:

do.call(rbind.data.frame,by(dat, dat$year, function(x) 
  lapply(x, function(y) { 
    t <- table(y)
    names(t)[which.max(t)]
  })))

#       p1 p2 p3 year
# 1970  a  d  e 1970
# 1985  b  c  d 1985
# 1999  b  c  d 1999

答案 1 :(得分:3)

仅使用基本R功能,您可以按如下方式解决此问题。

as.data.frame(t(
   sapply(split(sample, sample$year), function(x) {

      # for each x - data frame subset such grouped by year
      apply(x, 2, function(y) { 

          # for each y, i.e. column in x
          t <- table(y)
          names(t)[which.max(t)]  # return the label that occurs most often
      })

   })
))

结果:

##      p1 p2 p3 year
## 1970  a  d  e 1970
## 1985  b  c  d 1985
## 1999  b  c  d 1999

答案 2 :(得分:3)

使用dplyr你可以这样做:

require(dplyr)

sample %>%
  group_by(year) %>%
  summarise_each(funs(names(which.max(table(.)))))

sample %>%
  group_by(year) %>%
  summarise(p1 = names(which.max(table(p1))),
            p2 = names(which.max(table(p2))),
            p3 = names(which.max(table(p3))))

两种情况都有结果:

#  year p1 p2 p3 
#1 1970  a  d  e
#2 1985  b  c  d
#3 1999  b  c  d

如果您有很多列,并且您希望对除分组变量(本例中为年份)之外的所有列执行相同的操作,则第一种方法是一个不错的选择。如果列数较少,则第二种方法是合适的。基本上,他们做同样的事情。

修改

使用summarise_each,您还可以指定想要包含在操作中或要包含的列(并排除所有其他列)。因此,假设您的样本数据有100列p1 ... p100,并且您希望对除p1和p3之外的所有列执行此操作,您可以指定:

sample %>%
  group_by(year) %>%
  summarise_each(funs(names(which.max(table(.)))), -c(p1, p3))

反过来说,你可以指定只为这两列做到这一点:

sample %>%
  group_by(year) %>%
  summarise_each(funs(names(which.max(table(.)))), p1, p3)

并且,您可以在funs内的summarise_each参数中添加更多函数。