计算data.frame子集中数字的出现次数
我在R中有一个数据帧,类似于下面的。实际上,我真正的“df”数据帧比这里的要大得多,但我真的不想把任何人搞糊涂,所以我尽量简化事情 这是数据框计算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
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))