让我们拥有此数据
> allt <- data.frame(day = rep(c("mon", "tue", "wed"), each =3), id = c(1:3,2:4,3:5))
> allt
day id
1 mon 1
2 mon 2
3 mon 3
4 tue 2
5 tue 3
6 tue 4
7 wed 3
8 wed 4
9 wed 5
在最后一个数据框中,我们可以看到对于“星期一”,我们具有id [1,2,3],对于“星期二”,我们具有id [2,3,4]。因此,如果我们使这些向量相交,我们将得到[2,3],如果我们使它们并集,我们将得到[1,2,3,4]。这些向量的长度分别为2和4,比率为0.5。那就是我想要的电话号码。
因此,我正在寻找一种通用的方法,如何针对所有可能的组合在更多类别中获得该比率。
结果的格式可能类似于相关矩阵。为了清楚起见,我对2类交叉路口和并集感兴趣,因此例如,我不需要4路交叉路口(周一,周二,周三,周四)-只需2天交叉路口即可。
答案 0 :(得分:8)
也许是这样吗?
days <- levels(allt$day)
f <- function(x, y) {
xids <- allt$id[allt$day == x]
yids <- allt$id[allt$day == y]
length(intersect(xids, yids)) / length(union(xids, yids))
}
f <- Vectorize(f)
outer(days, days, f)
# [,1] [,2] [,3]
# [1,] 1.0 0.5 0.2
# [2,] 0.5 1.0 0.5
# [3,] 0.2 0.5 1.0
(可选)通过管道将其传输到set_colnames(days)
和set_rownames(days)
答案 1 :(得分:1)
这应该可以解决问题,您还可以进行更多组合,但要更改combn函数中的值。
# Creating your dataset
monday<-data.frame(day=rep("mon",3),id=c(1:3))
tuesday<-data.frame(day=rep("tue",3),id=c(2:4))
saturday<-data.frame(day=rep("sat",3),id=c(3:5))
allt<-rbind(monday,tuesday,saturday)
# Creating a list of values pr day
library(dplyr)
aggregated_form <- allt %>%
group_by(day) %>%
summarise(ids = list(id))
# Function takes a list with two vectors and make intersect/join
intersecter <- function(list_of_lists) {
vec1 <- unlist(list_of_lists[1])
vec2 <- unlist(list_of_lists[2])
my_intersect <- intersect(vec1, vec2)
my_union <- union(vec1, vec2)
ratio <- length(my_intersect)/length(my_union)
return(ratio)
}
# Creates strings with all combinations
combination <- sapply(combn(aggregated_form$day,2, simplify = FALSE), paste, collapse = "-")
# Calculates you value for all combinations
values <- combn(aggregated_form$ids, 2, FUN = intersecter)
# Generates a dataframe with results
results <- data.frame(comb = combination,
value = values)
results
comb value
1 mon-tue 0.5
2 mon-sat 0.2
3 tue-sat 0.5
答案 2 :(得分:1)
combn(unique(allt$day), 2, function(x)
{length(intersect(allt[allt$day == x[1],]$id, allt[allt$day == x[2],]$id)) / length(unique(allt[allt$day == x[1] | allt$day == x[2],]$id))
}, F
)
[[1]]
[1] 0.5
[[2]]
[1] 0.2
[[3]]
[1] 0.5
编辑:创建“ day-combinations-names”,可以执行类似的操作以按照相应的比率获得比率:
lapply(combn(unique(allt$day), 2, ,F), paste, collapse = "-")
[[1]]
[1] "mon-tue"
[[2]]
[1] "mon-sat"
[[3]]
[1] "tue-sat"
答案 3 :(得分:1)
首先为相交结果创建一个矩阵:
int<-mat.or.vec(nr=length(unique(allt$day)),nc=length(unique(allt$day)))
colnames(int)<-unique(allt$day)
rownames(int)<-unique(allt$day)
联合的复制矩阵:
un<-int
计算相交和并集:
for(col in colnames(int)){
for(row in colnames(int)){
int[row,col]<-length(intersect(allt[allt$day==col,"id"],allt[allt$day==row,"id"]))
un[row,col]<-length(union(allt[allt$day==col,"id"],allt[allt$day==row,"id"]))
}
}
然后,您只需将两个矩阵相除即可。
int/un
mon tue sat
mon 1.0 0.5 0.2
tue 0.5 1.0 0.5
sat 0.2 0.5 1.0