遍历列表以匹配具有多个匹配项的值

时间:2018-11-25 20:32:26

标签: r

我感兴趣的是循环浏览诊断代码列表,如果该值匹配,并使用先前计算的风险评分填充新变量,并且如果存在多个匹配项,则使用最高风险评分填充新变量。

我希望采用原始数据集的长格式,并为每个ID匹配风险分数最高的proc编号,并将proc编号和风险评分存储在单独的变量中。

我有一些使用if循环在宽数据中执行类似操作的经验,但是无法弄清楚如何使用这种方法。我没有匹配然后存储最高值的经验,所以甚至不知道从哪里开始。

数据以查看我要得到什么:

这是来自诊断代码的数据

dz <-c("disease_1", "disease_2", "disease_3", "disease_4")
code <-c(124, 546, 890, 898)
risk_score <-c(10, 122, 45, 98)
df <-data.frame(dz, code, risk_score)

还有我感兴趣的模拟数据集

 id <- c(1,1,1,2,2,2,2,3,3,4,4,4,4,4,4,5,5,5)
 proc <-c(244,546,234,345,890,123,434,634,233,345,124,234,634,546,789,890,567,124)
 proc<-as.character(proc)
 data<-data.frame(id, proc)

所以我想要实现的是这样的

id<-c(1,2,3,4,5)
code_match<-c(546,890,124,546,890)
highest_risk_score <-c(122,45,10,122,45)
output_df<-data.frame(id, code_match, highest_risk_score)

具有此输出

  id code_match highest_risk_score
1  1        546                122
2  2        890                 45
3  3        124                 10
4  4        546                122
5  5        890                 45

其中id是标识符,code_match是具有最高风险得分的代码,而high_risk_score是风险得分的值(该id的最高值)。

1 个答案:

答案 0 :(得分:1)

我们将使用另一种方式创建这些数据框:

data.frame(
  dz = c("disease_1", "disease_2", "disease_3", "disease_4"),
  code = as.character(c(124, 546, 890, 898)),
  risk_score = c(10, 122, 45, 98),
  stringsAsFactors = FALSE
) -> df

data.frame(
  id = c(1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5),
  proc = as.character(c(244, 546, 234, 345, 890, 123, 434, 634, 233, 345, 124, 234, 634, 546, 789, 890, 567, 124)),
  stringsAsFactors = FALSE
) -> data

这是一种方法(在tidyverse中以R为基数):

57个编译的依赖项tidyverse解决方案:

library(tidyverse)

filter(data, proc %in% df$code) %>%
  left_join(df, by=c("proc"="code")) %>%
  group_by(id) %>%
  top_n(1) %>%
  slice(1) %>%
  select(id, code_match = proc, highest_risk_score = risk_score)
## # A tibble: 4 x 3
## # Groups:   id [4]
##      id code_match highest_risk_score
##   <dbl> <chr>                   <dbl>
## 1    1. 546                      122.
## 2    2. 890                       45.
## 3    4. 546                      122.
## 4    5. 890                       45.

0(好吧,1 — stats —与R一起骑行时要使用)Base R解决方案

tmp <- merge(data[with(data, proc %in% df$code),], df, by.x = "proc", by.y = "code")

do.call(
  rbind.data.frame,
  lapply(
    split(tmp, tmp$id),
    function(x) {
      x[which.max(x$risk_score),]
    }
  )
)[,-3] -> tmp

setNames(tmp[,c(2,1,3)], c("id", "code_match", "highest_risk_score"))
##   id code_match highest_risk_score
## 1  1        546                122
## 2  2        890                 45
## 4  4        546                122
## 5  5        890                 45

您没有提到如何处理不匹配项,因此只会忽略它们。