首页 > 解决方案 > 如何根据另一个数据库中的记分卡给每个数据框值打分?

问题描述

我正在尝试为(以下两者)的values相对创建记分卡scorecard

values <- data.frame(A= c(-200,-150,-100,0,100),
                     B= c(100,0,-101,-201,-300),
                     C= c(-400,400,500,-500,250),
                     D= c(NA,NA,-1000,-1000,-1000),
                     E= c(1000,1000,1,-1000,-2000))

scorecard <- data.frame(Names = c("A","B","C","D","E"), 
                        "Score5" = c(-100,-200,-300,-400,-500))

values
     A    B    C     D     E
1 -200  100 -400 -1000  1000
2 -150    0  400 -1000  1000
3 -100 -101  500 -1000     1
4    0 -201 -500 -1000 -1000
5  100 -300  250 -1000 -2000

如果 A 的值 < -100(即scorecard[1,2]),记分卡数据框应该说 5,否则应该说 0。我想在一个数据框中对所有 A、B、C、D 和 E 执行此操作。所需的输出是:

#  A B C  D E
#1 5 0 5 NA 0
#2 5 0 0 NA 0
#3 0 0 0  5 0
#4 0 5 5  5 5
#5 0 5 0  5 5

我尝试了以下方法 - 这需要打包的 xts:install.packages("xts")但我并没有完全做到。

pointsfunction <- function(value)  {
  points <- c()
  for(i in names) {
    index = which(colnames(value)==i)
    data_start <- which(!is.na(value))[1]
    points[1:(data_start -1)] <- NA
    for(a in (data_start):(length(value))) {
      if(value[a] < scorecard[index, 2]) {
        points[a] <- -5
      } else {
        points[a] <- 0
      }
    }
  }
  points <- reclass(points, value)
  return(points)
}

scorecardpoints <- as.data.frame(lapply(values, pointsfunction))

我收到以下错误:

if (value[a] < scorecard[index, 2]) { : 参数长度为零 调用自:FUN(X[[i]], ...)

有任何想法吗?

标签: rdataframelapply

解决方案


使用dplyrtidyr您可以尝试:

library(dplyr)
library(tidyr)

values %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row, names_to = 'Names') %>%
  left_join(scorecard, by = 'Names') %>%
  mutate(value = if_else(value < Score5, 5, 0)) %>%
  select(-Score5) %>%
  pivot_wider(names_from = Names, values_from = value) %>%
  select(-row)

或者也许是一个更简单的基本 R 选项:

mat <- sweep(values, 2, scorecard$Score5[match(names(values), scorecard$Names)], `<`)
values[mat] <- 5
values[!mat] <- 0
values

#  A B C  D E
#1 5 0 5 NA 0
#2 5 0 0 NA 0
#3 0 0 0  5 0
#4 0 5 5  5 5
#5 0 5 0  5 5

推荐阅读