我有一个如下所示的数据结构
id year club
"A" "2010" "C1"
"B" "2010" "C1"
"C" "2010" "C2"
"A" "2011" "C1"
"B" "2011" "C2"
等等。我的问题是逐年创建一个矩阵,其中每个独特的个体固定在一行,每个独特的俱乐部固定在一列。如果在给定的年份,个人访问俱乐部,则相应的相交单元格取值为 1,否则为 0。
非常感谢您对此的任何帮助。
谢谢阿努普
我有一个如下所示的数据结构
id year club
"A" "2010" "C1"
"B" "2010" "C1"
"C" "2010" "C2"
"A" "2011" "C1"
"B" "2011" "C2"
等等。我的问题是逐年创建一个矩阵,其中每个独特的个体固定在一行,每个独特的俱乐部固定在一列。如果在给定的年份,个人访问俱乐部,则相应的相交单元格取值为 1,否则为 0。
非常感谢您对此的任何帮助。
谢谢阿努普
在基础 R 中,我会使用by
and xtabs
:
by(dat, dat$year, with, as.matrix(xtabs(~ id + club) * 1L))
它返回一个矩阵列表(每年一个)。另外,我建议不要乘以1L
返回布尔矩阵。
Edit1:按照建议,您还可以很容易地创建列联表:
table(dat[c("id", "club", "year")])
Edit2:我看到你对里卡多回答的评论,也许这就是你要找的:
library(plyr)
ddply(dat, .(year, id), with, 1L * (table(club) > 0))
# year id C1 C2
# 1 2010 A 1 0
# 2 2010 B 1 0
# 3 2010 C 0 1
# 4 2011 A 1 0
# 5 2011 B 0 1
您可能还想使用.drop = FALSE
来获取所有 (6) 个可能的年份/id 组合:
ddply(dat, .(year, id), with, 1L * (table(club) > 0), .drop = FALSE)
# year id C1 C2
# 1 2010 A 1 0
# 2 2010 B 1 0
# 3 2010 C 0 1
# 4 2011 A 1 0
# 5 2011 B 0 1
# 6 2011 C 0 0
这种单线解决方案输出单个数据帧,而不是像迄今为止发布的其他解决方案那样的单独矩阵。它需要reshape2
包,如果你以前从未使用过它,它对这类事情非常有用。
require(reshape2)
df = data.frame(id=c('a','b','c','a','b')
,year=c(2010,2010,2010,2011,2011)
,club=c('c1','c1','c2','c1','c2')
)
result = dcast(df, year + id ~ club, fun.aggregate=length, drop=F)
> result
year id c1 c2
1 2010 a 1 0
2 2010 b 1 0
3 2010 c 0 1
4 2011 a 1 0
5 2011 b 0 1
6 2011 c 0 0 # If you don't want this record, use: drop=T
根据评论,合适的格式是三维数组或 data.frames / data.tables 列表。
library(data.table)
DT <- data.table
### create a template matrix
# find all unique ID's and unique Club's
ids <- unique(DT$id)
clubs <- unique(DT$club)
# matrix template based on the number of ids & clubs
mat.template <- matrix(0L, nrow=length(ids), ncol=length(clubs), dimnames=list(ids, clubs))
# iterate over the unique values of year
DT <- data.table(dat, key="id,club")
res <- lapply(unique(DT$year), function(y) {
# index the matrix by the DT where y == year. Set those values to 1
mat <- copy(mat.template)
mat[as.matrix(DT[y==year, list(id, club)])] <- 1
mat
})
setattr(res, "names", unique(DT$year))
res
$`2010`
C1 C2
A 1 0
B 1 0
C 0 1
$`2011`
C1 C2
A 1 0
B 0 1
C 0 0