在R中的表中压缩/合并单元格

时间:2014-09-25 22:14:56

标签: r split

我试图用R中的表做某事。

该表以这样的方式进入脚本

          M   P
Position1 34  56
Position2 45  23
Position3 89  78
Position1 56  45
Position3 54  35
Position2 56  89

在分析了这个脚本后,理想情况下,我希望最终输出为:

          M   P
Position1 90  101
Position2 101 102
Position3 143 113

基本上我总结了M和P的位置总数。我想知道是否有更简单的方法来做到这一点。这些职位将是随机的。有没有办法可以按位置拆分数据表?

6 个答案:

答案 0 :(得分:2)

如果您有多列并且数据集很大,那么您可以使用summarise_each中的dplyr,当然数据是data.frame(从帖子中可以看出,目前尚不清楚拥有matrixdata.frame

library(dplyr)
 dat %>% 
      group_by(Pos) %>% 
      summarise_each(funs(sum=sum(., na.rm=TRUE)))
 #        Pos   M   P
 #1 Position1  90 101
 #2 Position2 101 112
 #3 Position3 143 113

或者我用于更大数据集的另一个选项是data.table。从@Ananda Mahto的基准测试来看,它是速度的明显赢家。

 library(data.table)
 setDT(dat)[, lapply(.SD, sum, na.rm=TRUE), by=Pos]
 #        Pos   M   P
 #1: Position1  90 101
 #2: Position2 101 112
 #3: Position3 143 113

如果您使用的是matrix,则无需将其转换为data.frame并为row.names创建新列。 (也许,这个选项仍然有效)

  do.call(rbind, by(m1, list(rownames(m1)), colSums, na.rm=TRUE))
  #            M   P
  #Position1  90 101
  #Position2 101 112
  #Position3 143 113

或者在处理matrices

时采用稍微有效的方法
   library(reshape2)
   acast(melt(m1), Var1~Var2, value.var="value", sum, na.rm=TRUE)
   #           M   P
   #Position1  90 101
   #Position2 101 112
   #Position3 143 113

数据

rownames作为列添加,因为data.frame不允许重复的rownames。

dat <- structure(list(Pos = c("Position1", "Position2", "Position3", 
"Position1", "Position3", "Position2"), M = c(34L, 45L, 89L, 
56L, 54L, 56L), P = c(56L, 23L, 78L, 45L, 35L, 89L)), .Names = c("Pos", 
"M", "P"), class = "data.frame", row.names = c(NA, -6L))


m1 <- structure(c(34, 45, 89, 56, 54, 56, 56, 23, 78, 45, 35, 89), .Dim = c(6L, 
2L), .Dimnames = list(c("Position1", "Position2", "Position3", 
"Position1", "Position3", "Position2"), c("M", "P")))

答案 1 :(得分:1)

还有一个,只是为了好玩。这个产生你在帖子中显示的结构。

t(sapply(split(dat[-1], dat$Pos), colSums))
#             M   P
# Position1  90 101
# Position2 101 112
# Position3 143 113

答案 2 :(得分:1)

此答案仅适用于您正在处理matrix(例如&#34; m1&#34; @ akrun答案中共享的数据集):

xtabs(Freq ~ Var1 + Var2, data.frame(as.table(m1)))
#            Var2
# Var1          M   P
#   Position1  90 101
#   Position2 101 112
#   Position3 143 113

答案 3 :(得分:0)

首先获取你的rownames

rows<-unique(rownames(yourDataFrame))

确保有独特之处或我们会获得大量重复

然后你可以在这里做一些不同的事情,包plyr会派上用场,但只要使用基础R就可以使用lapply来计算你的总和

result<-lapply(rownames, function(rname){
         subsetDF<-yourDataFrame[rname,]
         apply(subsetDF, 2, sum)
    }
)

要将其分解,您可以获取所有的rownames,并通过该rowname的行以lapply子集数据帧。接下来,对该子集应用sum,获取列,然后将其输出到列表。然后,您可以执行类似rbindlist(result)的操作来获取结果数据帧。

绝对不是最有效的方法,但这是我想到的第一件事

答案 4 :(得分:0)

你想要的是聚合函数。

假设您将表格存储为data,然后尝试

condensedData <- aggregate(data, by=list(position), FUN=sum, na.rm=TRUE)

如果这并不能完全符合您的要求,请尝试使用聚合函数进行试验。重要的输入是byFUNby告诉aggregate您希望通过哪个列唯一标识结果,而FUN告诉aggregate如何将数字与相同的by结合起来。 FUN可以&#34;总和&#34;,&#34;意思&#34;等...

答案 5 :(得分:0)

'aggregate'需要按如下方式使用:

> ddf
         V1 V2 V3
1 Position1 34 56
2 Position2 45 23
3 Position3 89 78
4 Position1 56 45
5 Position3 54 35
6 Position2 56 89


> a1 = aggregate(V2~V1, ddf, sum)
> a2 = aggregate(V3~V1, ddf, sum)
> merge(a1, a2)
         V1  V2  V3
1 Position1  90 101
2 Position2 101 112
3 Position3 143 113