如何根据组成员资格对数据框进行子集化?

时间:2014-09-22 02:29:14

标签: r unique subset

我想编写一个函数,以便根据组成员资格对(可能很大的)数据框进行子集化,其中“group”是一组列值的唯一组合。 例如,我想根据前两列(Loc1和Loc2)的唯一组合对下面的数据框进行子集化。

Loc1 <- c("A","A","A","A","B","B","B")  
Loc2 <- c("a","a","b","b","a","a","b")  
Dat1 <- c(1,1,1,1,1,1,1)  
Dat2 <- c(1,2,1,2,1,2,2)  
Dat3 <- c(2,2,4,4,6,5,3)  
DF=data.frame(Loc1,Loc2,Dat1,Dat2,Dat3)  

  Loc1 Loc2 Dat1 Dat2 Dat3
1    A    a    1    1    2
2    A    a    1    2    2
3    A    b    1    1    4
4    A    b    1    2    4
5    B    a    1    1    6
6    B    a    1    2    5
7    B    b    1    2    3

我想返回(i)组的数量(即4),(ii)每组中的数字(即c(2,2,2,1),以及(iii)重新标记行,以便我可以根据组成员资格进一步分析数据框架(例如,对于ANOVA和MANOVA)(即

Group<-as.factor(c(1,1,2,2,3,3,4))
Data <- cbind(Group,DF[,-1:-2])

  Group Dat1 Dat2 Dat3
1     1    1    1    2
2     1    1    2    2
3     2    1    1    4
4     2    1    2    4
5     3    1    1    6
6     3    1    2    5
7     4    1    2    3

)。

到目前为止,我所管理的只是获得群组的数量,而且我怀疑有更好的方法可以做到这一点:

nrow(unique(DF[,1:2]))  

我希望避免使用for循环,因为我担心函数很慢。

我已经尝试过转换为数据矩阵,以便我可以连接行值,但我也无法使用它。

非常感谢

3 个答案:

答案 0 :(得分:0)

你可以尝试:

使用Groupunique的{​​{1}}级组合创建Loc1列。

Loc2

然后,如果您需要按组对数据集进行子集化,则可以使用 indx <- paste(DF[,1], DF[,2]) DF$Group <- as.numeric(factor(indx, unique(indx))) #query No (iii) DF1 <- DF[-(1:2)][,c(4,1:3)] # Group Dat1 Dat2 Dat3 #1 1 1 1 2 #2 1 1 2 2 #3 2 1 1 4 #4 2 1 2 4 #5 3 1 1 6 #6 3 1 2 5 #7 4 1 2 3 table(DF$Group) #(No. ii) #1 2 3 4 #2 2 2 1 length(unique(DF$Group)) #(i) #[1] 4 拆分数据集以创建Group列表元素列表

4

更新

如果您有多列,您仍然可以尝试:

  split(DF1, DF1$Group)

你可以创建一个函数;

   ColstoGroup <- 1:2
   indx <- apply(DF[,ColstoGroup], 1, paste, collapse="") 
   as.numeric(factor(indx, unique(indx)))
   #[1] 1 1 2 2 3 3 4

答案 1 :(得分:0)

这会获得所有三个查询。

从前两列的table开始,然后使用该数据。

> (tab <- table(DF$Loc1, DF$Loc2))
#   
#    a b
#  A 2 2
#  B 2 1 
#
> (ct <- c(tab))                                       ## (ii)
# [1] 2 2 2 1
> length(unlist(dimnames(tab)))                        ## (i)
# [1] 4
> cbind(Group = rep(seq_along(ct), ct), DF[-c(1,2)])   ## (iii)
#  Group Dat1 Dat2 Dat3  
# 1     1    1    1    2
# 2     1    1    2    2
# 3     2    1    1    4
# 4     2    1    2    4
# 5     3    1    1    6
# 6     3    1    2    5
# 7     4    1    2    3

答案 2 :(得分:0)

借用this answer并使用一些dplyr惯用语来借词:

library(dplyr)

Loc1 <- c("A","A","A","A","B","B","B")  
Loc2 <- c("a","a","b","b","a","a","b")  
Dat1 <- c(1,1,1,1,1,1,1)  
Dat2 <- c(1,2,1,2,1,2,2)  
Dat3 <- c(2,2,4,4,6,5,3)  

DF <- data.frame(Loc1, Loc2, Dat1, Dat2, Dat3)  


emitID <- local({
    idCounter <- -1L
    function(){
        idCounter <<- idCounter + 1L 
    }
})

DF %>% group_by(Loc1, Loc2) %>% mutate(Group=emitID())

##   Loc1 Loc2 Dat1 Dat2 Dat3 Group
## 1    A    a    1    1    2     0
## 2    A    a    1    2    2     0
## 3    A    b    1    1    4     1
## 4    A    b    1    2    4     1
## 5    B    a    1    1    6     2
## 6    B    a    1    2    5     2
## 7    B    b    1    2    3     3