7

我有一个如下所示的数据框,但行数更多

> df<-data.frame(x1=c(1,1,0,0,1,0),x2=c("a","a","b","a","c","c"))
> df
  x1 x2
1  1  a
2  1  a
3  0  b
4  0  a
5  1  c
6  0  c

df我想要一个数据框,其中行是唯一值,df$x2col1 是与每个字母关联的 1 的比例,col2 是每个字母的计数。所以,我的输出是

 > getprops(df)
  prop   count
a  .6666   3
b  0       1
c  0.5     2

我可以想出一些复杂的、肮脏的方法来做到这一点,但我正在寻找一些简短而有效的方法。谢谢

4

5 回答 5

6

我喜欢@RicardoSaporta 的解决方案(+1),但您也可以使用?prop.table

> df<-data.frame(x1=c(1,1,0,0,1,0),x2=c("a","a","b","a","c","c"))
> df
  x1 x2
1  1  a
2  1  a
3  0  b
4  0  a
5  1  c
6  0  c
> tab <- table(df$x2, df$x1)
> tab

    0 1
  a 1 2
  b 1 0
  c 1 1
> ptab <- prop.table(tab, margin=1)
> ptab

            0         1
  a 0.3333333 0.6666667
  b 1.0000000 0.0000000
  c 0.5000000 0.5000000
> dframe <- data.frame(values=rownames(tab), prop=ptab[,2], count=tab[,2])
> dframe
  values      prop count
a      a 0.6666667     2
b      b 0.0000000     0
c      c 0.5000000     1

如果你愿意,你可以把它放在一个函数中:

getprops <- function(values, indicator){
  tab    <- table(values, indicator)
  ptab   <- prop.table(tab, margin=1)
  dframe <- data.frame(values=rownames(tab), prop=ptab[,2], count=tab[,2])
  return(dframe)
}

> getprops(values=df$x2, indicator=df$x2)
  values      prop count
a      a 0.6666667     2
b      b 0.0000000     0
c      c 0.5000000     1
于 2013-07-07T04:23:16.517 回答
4

尝试安装 plyr 并运行

library(plyr)
df <- data.frame(x1=c(1, 1, 0, 0, 1, 0),
                 label=c("a", "a", "b", "a", "c", "c"))
ddply(df, .(label), summarize, prop = mean(x1), count = length(x1))
#   label      prop count
# 1     a 0.6666667     3
# 2     b 0.0000000     1
# 3     c 0.5000000     2

它在底层应用了类似于此的拆分/应用/组合方法:

do.call(rbind, lapply(split(df, df$x2),
                            with, list(prop  = mean(x1),
                                       count = length(x1))))
于 2013-07-07T02:05:47.757 回答
4

这是一个单行代码data.table

> DT[, list(props=sum(x1) / .N, count=.N), by=x2]
   x2     props count
1:  a 0.6666667     3
2:  b 0.0000000     1
3:  c 0.5000000     2


在哪里DT <- data.table(df)

于 2013-07-07T16:50:19.053 回答
3

我不确定这是否符合您的要求。

df<-data.frame(x1=c(1,1,0,0,1,0),x2=c("a","a","b","a","c","c"))

ones <- with(df, aggregate(x1 ~ x2, FUN = sum))
count <- table(df$x2)
prop <- ones$x1 / count

df2 <- data.frame(prop, count)
df2

rownames(df2) <- df2[,3]
df2 <- df2[,c(2,4)]
colnames(df2) <- c('prop', 'count')
df2

       prop count
a 0.6666667     3
b 0.0000000     1
c 0.5000000     2
于 2013-07-07T02:28:06.277 回答
2

尝试使用table

tbl <- table(df$x1, df$x2)  
#    a b c
#  0 1 1 1
#  1 2 0 1


tbl["1",] / colSums(tbl)
#          a         b         c 
#  0.6666667 0.0000000 0.5000000 

对于漂亮的输出使用:

data.frame(proportions=tbl["1",] / colSums(tbl))
  proportions
a   0.6666667
b   0.0000000
c   0.5000000
于 2013-07-07T02:32:48.163 回答