考虑我有四个对象(a,b,c,d
),我要求五个人根据他们的外貌或其他东西标记它们(类别1或2)。五个人为这些物体提供的标签显示为
df <- data.frame(a = c(1,2,1,2,1), b=c(1,2,2,1,1), c= c(2,1,2,2,2), d=c(1,2,1,2,1))
以表格格式,
---------
a b c d
---------
1 1 2 1
2 2 1 2
1 2 2 1
2 1 2 2
1 1 2 1
----------
现在我想计算一组对象被赋予相同标签(1或2)的百分比。例如,对象a,b和d由5个人中的3个人给出相同的标签。所以它的百分比是3/5(= 60%)。虽然对象a和d被所有人给予相同的标签,所以它的百分比是5/5(= 100%)
我可以手动计算这个统计数据,但在原始数据集中,我有50个这样的对象,人数为30,标签为4(1,2,3和4)。如何自动为这个更大的数据集计算此类统计数据? R
中是否有可以计算此类统计信息的现有软件包/工具?
注意:一个组可以是任何大小。在第一个例子中,一个组由a,b和d组成,而第二个例子组由a和d组成。
答案 0 :(得分:4)
如果您有数字评级,则可以使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div class="clsname">scroll to here</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
检查每个评估者之间是否始终存在diff
差异:
0
将函数应用于示例组时,结果与预期一致:
f <- function(cols, data) {
sum(colSums(diff(t(data[cols]))==0)==(length(cols)-1)) / nrow(data)
}
答案 1 :(得分:3)
这里有两个任务:第一,列出所有相关组合,第二,评估和聚合行方向相似性。 combn
可以启动第一项任务,但需要进行一些按摩才能将结果排列到整齐的列表中。第二个任务可以用prop.table
来处理,但这里直接计算更简单。
这里我使用了tidyverse
语法(主要是purrr
,这对处理列表有帮助),但如果你愿意,可以转换成基数。
library(tidyverse)
map(2:length(df), ~combn(names(df), .x, simplify = FALSE)) %>% # get combinations
flatten() %>% # eliminate nesting
set_names(map_chr(., paste0, collapse = '')) %>% # add useful names
# subset df with combination, see if each row has only one unique value
map(~apply(df[.x], 1, function(x){n_distinct(x) == 1})) %>%
map_dbl(~sum(.x) / length(.x)) # calculate TRUE proportion
## ab ac ad bc bd cd abc abd acd bcd abcd
## 0.6 0.2 1.0 0.2 0.6 0.2 0.0 0.6 0.2 0.0 0.0
答案 2 :(得分:2)
使用基本R函数,您可以:
groupVec = c("a","b","d")
transDF = t(as.matrix(DF))
subDF = transDF[rownames(transDF) %in% groupVec,]
subDF
# [,1] [,2] [,3] [,4] [,5]
# a 1 2 1 2 1
# b 1 2 2 1 1
# d 1 2 1 2 1
#if length of unique values is 1, it implies match across all objects, count unique values/total columns = match pct
match_pct = sum(sapply(as.data.frame(subDF), function(x) sum(length(unique(x))==1) ))/ncol(subDF)
match_pct
# [1] 0.6
将其包装成自定义功能:
fn_matchPercent = function(groupVec = c("a","d") ) {
transDF = t(as.matrix(DF))
subDF = transDF[rownames(transDF) %in% groupVec,]
match_pct = sum(sapply(as.data.frame(subDF), function(x) sum(length(unique(x))==1) ))/ncol(subDF)
outputDF = data.frame(groups = paste0(groupVec,collapse=",") ,match_pct = match_pct)
return(outputDF)
}
fn_matchPercent(c("a","d"))
# groups match_pct
# 1 a,d 1
fn_matchPercent(c("a","b","d"))
# groups match_pct
# 1 a,b,d 0.6
答案 3 :(得分:2)
试试这个:
find.unanimous.percentage <- function(df, at.a.time) {
cols <- as.data.frame(t(combn(names(df), at.a.time)))
names(cols) <- paste('O', 1:at.a.time, sep='')
cols$percent.unanimous <- 100*colMeans(apply(cols, 1, function(x) apply(df[x], 1, function(y) length(unique(y)) == 1)))
return(cols)
}
find.unanimous.percentage(df, 2) # take 2 at a time
O1 O2 percent.unanimous
1 a b 60
2 a c 20
3 a d 100
4 b c 20
5 b d 60
6 c d 20
find.unanimous.percentage(df, 3) # take 3 at a time
O1 O2 O3 percent.unanimous
1 a b c 0
2 a b d 60
3 a c d 20
4 b c d 0
find.unanimous.percentage(df, 4)
O1 O2 O3 O4 percent.unanimous
1 a b c d 0
答案 4 :(得分:1)
如果您的实际问题需要评估群集相同数据的各种选项,您似乎可能想要计算与您现在建议的实质上不同(更好?)的指标。
此http://cs.utsa.edu/~qitian/seminar/Spring11/03_11_11/IR2009.pdf概述了问题,但BCubed精确/召回指标通常用于NLP中的类似问题(例如http://alias-i.com/lingpipe/docs/api/com/aliasi/cluster/ClusterScore.html)。
答案 5 :(得分:0)
试试这段代码。它适用于您的示例,并且应该适用于扩展案例。
df <- data.frame(a = c(1,2,1,2,1), b=c(1,2,2,1,1), c= c(2,1,2,2,2), d=c(1,2,1,2,1))
# Find all unique combinations of the column names
group_pairs <- data.frame(t(combn(colnames(df), 2)))
# For each combination calculate the similarity
group_pairs$similarities <- apply(group_pairs, 1, function(x) {
sum(df[x["X1"]] == df[x["X2"]])/nrow(df)
})