R按规则计算数据框中每一行的最重要值
R Calculate most important value for each row in data frame by rules
我有一个问题,我在解决它时遇到了一些问题。
我有一个数据框,其中我在每行中收集了 4 个标签和相应的分数值。这是我的示例数据:
sample = data.frame("label1" = c("name1", "name1", "name3"), "score1" = c(0.88, 0.5, 0.4),
"label2" = c("name1", "name1", "name3"), "score2" = c(0.93, 0.6, 0.35),
"label3" = c("name2", "name1", "name4"), "score3" = c(0.49, 0.7, 0.8),
"label4" = c("name2", "name2", "name1"), "score4" = c(0.81, 0.8, 0.25), stringsAsFactors = FALSE)
现在我想根据以下规则为每一行计算最终标签和分数:
- 如果一个标签出现超过 2 次那么这是最终标签,对应的值是这个标签的得分值的平均值
- 如果一行中有两个不同的标签,都出现了两次,那么应该选择得分均值较高的标签,并选择相应的得分均值
- 如果一行中有两个以上不同的标签,则不清楚该选择哪个。所以应该有一个NA,对应的值也是NA。
我想到逐行循环数据帧并重组行以使用 aggregate
。这是我对第一行的处理方法:
pairs <- as.data.frame(matrix(as.vector(sample[1,]), ncol=2, byrow = TRUE))
pairs = data.frame("label" = unlist(pairs[,1], recursive = FALSE), "score" = unlist(pairs[,2], recursive = FALSE))
pairs$label = as.character(pairs$label)
aggregate(score~label, data=pairs, FUN = function(x) c(mean = mean(x), count = length(x) ))
到这里之后,我不知道如何执行上述规则。也许有更有效的方法来解决这个问题?
这是我想要的输出:
result = data.frame("label" = c("name1", "name1", NA), "score" = c(0.905, 0.6, NA))
提前致谢
就像你一样,我也认为重构数据并聚合它是可行的方法,这就是我在这里所做的:
library(dplyr)
sample$row_num <- 1:nrow(sample)
new_lst <- lapply(1:4,
function(x){
cols <- names(sample)[grepl(x, names(sample))]
sample[, c(cols, "row_num")] %>%
setNames(c( "label", "score", "row_num"))
})
sample_2 <- do.call(rbind, new_lst) %>%
group_by(row_num, label) %>%
summarise(cnt = n(),
score_avg = mean(score))
现在我遍历每一行并应用我使用 if-elseif-else 的规则来编码
lapply(1:nrow(sample),
function(x){
dat <- sample_2 %>% filter(row_num == x)
if(max(dat$cnt) > 2) {
label <- as.character(dat[which((dat$cnt) > 2), "label"])
score <- dat[dat$label == label, "score_avg"]
} else if (nrow(dat) > 2) {
label <- NA
score <- NA
} else {
label <- as.character(dat[which.max(dat$score_avg), "label"])
score <- max(dat$score_avg)
}
return(data.frame(# "row_num" = x, # you can un-comment here to have an indexed output
"label" = label, "score" = score))
}) %>%
data.table::rbindlist()
不是很优雅,但它完成了工作
希望对您有所帮助
我有一个问题,我在解决它时遇到了一些问题。 我有一个数据框,其中我在每行中收集了 4 个标签和相应的分数值。这是我的示例数据:
sample = data.frame("label1" = c("name1", "name1", "name3"), "score1" = c(0.88, 0.5, 0.4),
"label2" = c("name1", "name1", "name3"), "score2" = c(0.93, 0.6, 0.35),
"label3" = c("name2", "name1", "name4"), "score3" = c(0.49, 0.7, 0.8),
"label4" = c("name2", "name2", "name1"), "score4" = c(0.81, 0.8, 0.25), stringsAsFactors = FALSE)
现在我想根据以下规则为每一行计算最终标签和分数:
- 如果一个标签出现超过 2 次那么这是最终标签,对应的值是这个标签的得分值的平均值
- 如果一行中有两个不同的标签,都出现了两次,那么应该选择得分均值较高的标签,并选择相应的得分均值
- 如果一行中有两个以上不同的标签,则不清楚该选择哪个。所以应该有一个NA,对应的值也是NA。
我想到逐行循环数据帧并重组行以使用 aggregate
。这是我对第一行的处理方法:
pairs <- as.data.frame(matrix(as.vector(sample[1,]), ncol=2, byrow = TRUE))
pairs = data.frame("label" = unlist(pairs[,1], recursive = FALSE), "score" = unlist(pairs[,2], recursive = FALSE))
pairs$label = as.character(pairs$label)
aggregate(score~label, data=pairs, FUN = function(x) c(mean = mean(x), count = length(x) ))
到这里之后,我不知道如何执行上述规则。也许有更有效的方法来解决这个问题? 这是我想要的输出:
result = data.frame("label" = c("name1", "name1", NA), "score" = c(0.905, 0.6, NA))
提前致谢
就像你一样,我也认为重构数据并聚合它是可行的方法,这就是我在这里所做的:
library(dplyr)
sample$row_num <- 1:nrow(sample)
new_lst <- lapply(1:4,
function(x){
cols <- names(sample)[grepl(x, names(sample))]
sample[, c(cols, "row_num")] %>%
setNames(c( "label", "score", "row_num"))
})
sample_2 <- do.call(rbind, new_lst) %>%
group_by(row_num, label) %>%
summarise(cnt = n(),
score_avg = mean(score))
现在我遍历每一行并应用我使用 if-elseif-else 的规则来编码
lapply(1:nrow(sample),
function(x){
dat <- sample_2 %>% filter(row_num == x)
if(max(dat$cnt) > 2) {
label <- as.character(dat[which((dat$cnt) > 2), "label"])
score <- dat[dat$label == label, "score_avg"]
} else if (nrow(dat) > 2) {
label <- NA
score <- NA
} else {
label <- as.character(dat[which.max(dat$score_avg), "label"])
score <- max(dat$score_avg)
}
return(data.frame(# "row_num" = x, # you can un-comment here to have an indexed output
"label" = label, "score" = score))
}) %>%
data.table::rbindlist()
不是很优雅,但它完成了工作
希望对您有所帮助