计算data.frame子集中数字的出现次数

计算data.frame子集中数字的出现次数,r,subset,R,Subset,我在R中有一个数据帧,类似于下面的。实际上,我真正的“df”数据帧比这里的要大得多,但我真的不想把任何人搞糊涂,所以我尽量简化事情 这是数据框 id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3) a <-c(3,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3) b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1

我在R中有一个数据帧,类似于下面的。实际上,我真正的“df”数据帧比这里的要大得多,但我真的不想把任何人搞糊涂,所以我尽量简化事情

这是数据框

id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3)   
a <-c(3,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3)
b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1,3,2,1,1,1,2,1,3,1,2,2,1,3,3,2,3,2)
c <-c(1,3,2,3,2,1,2,3,3,2,2,3,1,2,3,3,3,1,1,2,3,3,1,2,2,3,2,2,3,2)
d <-c(3,3,3,1,3,2,2,1,2,3,2,2,2,1,3,1,2,2,3,2,3,2,3,2,1,1,1,1,1,2)
e <-c(2,3,1,2,1,2,3,3,1,1,2,1,1,3,3,2,1,1,3,3,2,2,3,3,3,2,3,2,1,3)

df <-data.frame(id,a,b,c,d,e)
df
只是简单地解释一下我的结果:在“a”列中(仅关于“id”列中有数字“1”的记录),我们可以说数字“1”出现了3次,数字“3”出现了7次

再一次,给你看另一个例子。对于列“a”和id号“2”(对于后面的分组,请再次参见列“id”):

让我再解释一下:在“a”列中,关于“id”列中只有数字“2”的观察,我们可以说数字“1”出现了4次,数字“2”出现了3次,数字“3”出现了3次

这就是我想做的。计算每个自定义定义子集的数字出现次数(然后将这些值收集到数据框中)。我知道这不是一项困难的任务,但问题是我必须定期更改输入“df”数据帧,因此行和列的总数可能会随着时间的推移而改变

到目前为止,我所做的是用列分隔“df”数据帧,如下所示:

as.numeric(table(df[1:10,2]))

##The results are:
[1] 3 7
for (z in (2:ncol(df))) assign(paste("df",z,sep="."),df[,z])
所以df.2将指df$a,df.3将等于df$b,df.4将等于df$c等等。但我现在真的被卡住了,我不知道如何前进


有没有合适的“自动”方法来解决这个问题?

我相信有人会有比这个更优雅的解决方案,但是你可以用一个简单的函数和
plyr
包中的
dlply
拼凑起来

ColTables <- function(df) {
  counts <- list()
  for(a in names(df)[names(df) != "id"]) {
    counts[[a]] <- table(df[a])
  }
  return(counts)
}

results <- dlply(df, "id", ColTables)
对于id变量=2,column=a,根据上面的示例。

如何-

> library(reshape)

> dftab <- table(melt(df,'id'))
> dftab
, , value = 1

   variable
id  a b c d e
  1 3 8 2 2 4
  2 4 6 3 2 4
  3 4 2 1 5 1

, , value = 2

   variable
id  a b c d e
  1 0 1 4 3 3
  2 3 3 3 6 2
  3 1 4 5 3 4

, , value = 3

   variable
id  a b c d e
  1 7 1 4 5 3
  2 3 1 4 2 4
  3 5 4 4 2 5

结合使用
taply
apply
可以创建所需的数据:

tapply(df$id,df$id,function(x) apply(df[id==x,-1],2,table))
但是,当分组中没有所有元素时,如
1a
,结果将是该
id
组的列表,而不是一个漂亮的表(矩阵)


一种方法是使用
aggregate
函数,但您必须向数据帧添加一列

> df$freq <- 0
> aggregate(freq~a+id,df,length)
  a id freq
1 1  1    3
2 3  1    7
3 1  2    4
4 2  2    3
5 3  2    3
6 1  3    4
7 2  3    1
8 3  3    5
df$freq聚合(freq~a+id,df,length) 身份证号码 1 1 1 3 2 3 1 7 3 1 2 4 4 2 2 3 5 3 2 3 6 1 3 4 7 2 3 1 8 3 3 5 当然,您可以编写一个函数来执行此操作,因此更容易频繁地执行此操作,并且不必向实际数据帧中添加列

> frequency <- function(df,groups) {
+   relevant <- df[,groups]
+   relevant$freq <- 0
+   aggregate(freq~.,relevant,length)
+ }
> frequency(df,c("b","id"))
  b id freq
1 1  1    8
2 2  1    1
3 3  1    1
4 1  2    6
5 2  2    3
6 3  2    1
7 1  3    2
8 2  3    4
9 3  3    4

>frequency您没有说您希望如何获取数据。
by
函数可能会提供您喜欢的输出

by(df, df$id, function(x) lapply(x[,-1], table))

您可以使用一个系数来确保零计数通过:
lappy(拆分(df[-1],df$id),应用,2,函数(x)表(系数(x,1:3))
$`1`
$`1`$a

1 3 
3 7 

$`1`$b

1 2 3 
8 1 1 

$`1`$c

1 2 3 
2 4 4 

$`1`$d

1 2 3 
2 3 5 

$`1`$e

1 2 3 
4 3 3 


$`2`
  a b c d e
1 4 6 3 2 4
2 3 3 3 6 2
3 3 1 4 2 4

$`3`
  a b c d e
1 4 2 1 5 1
2 1 4 5 3 4
3 5 4 4 2 5
> df$freq <- 0
> aggregate(freq~a+id,df,length)
  a id freq
1 1  1    3
2 3  1    7
3 1  2    4
4 2  2    3
5 3  2    3
6 1  3    4
7 2  3    1
8 3  3    5
> frequency <- function(df,groups) {
+   relevant <- df[,groups]
+   relevant$freq <- 0
+   aggregate(freq~.,relevant,length)
+ }
> frequency(df,c("b","id"))
  b id freq
1 1  1    8
2 2  1    1
3 3  1    1
4 1  2    6
5 2  2    3
6 3  2    1
7 1  3    2
8 2  3    4
9 3  3    4
by(df, df$id, function(x) lapply(x[,-1], table))