首页 > 解决方案 > 使用 tidyverse 环境循环遍历数据帧,比较结果,并返回一个值。类似于excel中的vlookup功能

问题描述

我想下图总结了我的问题: 问题

不过,要说清楚。假设我有一个包含很多结果(f1、f2、f3 等)的数据框和另一个数据框,其中我对这些结果(f1、f2、f3)有一个“规范表”(在心理学中很常见) . 我需要将第一个数据帧中的结果与第二个数据帧中的结果进行比较,然后返回相应的“百分位数”和“分类”。然后,我需要继续对第一个数据帧中的所有其他变量执行此过程。

重要提示:假设我的值是 30,这个结果有两个百分位数(比如说 0.5 和 0.55),我需要保持最高的百分位数,因此是最高的分类。

我想留在 tidyverse 环境中。太感谢了!

那是代码:

normative_table <- structure(list(classification = c("Muito inferior", "inferior", 
                                                     "medio inferior", "medio inferior", "medio inferior", "medio inferior", 
                                                     "medio", "medio", "medio", "medio", "medio", "medio", "medio", 
                                                     "medio", "medio", "medio superior", "medio superior", "medio superior", 
                                                     "medio superior", "Superior", "Muito superior"), percentile = c(0, 
                                                                                                                     0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 
                                                                                                                     0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1), f1 = c(`0%` = 1, 
                                                                                                                                                                            `5%` = 1.1, `10%` = 1.3, `15%` = 1.4, `20%` = 1.4, `25%` = 1.5, 
                                                                                                                                                                            `30%` = 1.6, `35%` = 1.6, `40%` = 1.7, `45%` = 1.8, `50%` = 1.9, 
                                                                                                                                                                            `55%` = 1.9, `60%` = 2, `65%` = 2.1, `70%` = 2.3, `75%` = 2.5, 
                                                                                                                                                                            `80%` = 2.7, `85%` = 2.9, `90%` = 3.1, `95%` = 3.4, `100%` = 4.6
                                                                                                                     ), f2 = c(`0%` = 1, `5%` = 1.12, `10%` = 1.25, `15%` = 1.38, 
                                                                                                                               `20%` = 1.5, `25%` = 1.62, `30%` = 1.62, `35%` = 1.75, `40%` = 1.75, 
                                                                                                                               `45%` = 1.88, `50%` = 1.88, `55%` = 2, `60%` = 2, `65%` = 2.12, 
                                                                                                                               `70%` = 2.25, `75%` = 2.38, `80%` = 2.5, `85%` = 2.62, `90%` = 3, 
                                                                                                                               `95%` = 3.25, `100%` = 4.25), f3 = c(`0%` = 1, `5%` = 1.17, `10%` = 1.33, 
                                                                                                                                                                    `15%` = 1.5, `20%` = 1.67, `25%` = 1.83, `30%` = 1.83, `35%` = 2, 
                                                                                                                                                                    `40%` = 2.17, `45%` = 2.17, `50%` = 2.33, `55%` = 2.5, `60%` = 2.67, 
                                                                                                                                                                    `65%` = 2.67, `70%` = 2.83, `75%` = 2.83, `80%` = 3, `85%` = 3.17, 
                                                                                                                                                                    `90%` = 3.33, `95%` = 3.67, `100%` = 4.67)), row.names = c(NA, 
                                                                                                                                                                                                                               -21L), class = "data.frame")
items <- structure(list(id = c("1", "2", "3", "4", "5", "6", "7", "8", 
                               "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 
                               "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", 
                               "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", 
                               "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", 
                               "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", 
                               "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", 
                               "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", 
                               "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", 
                               "97", "98", "99", "100"), f1 = c(1.1, 1.5, 1.3, 1.4, 1.9, 2, 
                                                                2.5, 2.3, 2.2, NA, 1.9, 2, 2.7, 1.3, 2.9, 2.6, 1.9, 3, 1.6, 1.2, 
                                                                1.6, NA, 1.9, 2.2, 2.3, 4.4, 1.6, 1.2, 3.9, 2.7, 1.5, 2.2, 1.9, 
                                                                2, 1.5, 1.4, 3.1, 2.5, 1.1, 1.1, 1.2, NA, 1.5, 1.7, 2.8, 2.2, 
                                                                1.7, 1.8, 1.1, 3, 1.4, 2.8, 1.4, 1.9, 3.9, 2, 4.6, 2, 1.7, 1.7, 
                                                                2.5, 1.5, 3.3, 3.4, 1.6, 1.9, 2.5, 1.2, 1.4, 1.9, 2.5, 1.3, 2, 
                                                                1.4, 1.4, 3.4, 1.6, 1.7, 2.6, 2.8, 1.6, 3, 3, 1.5, 1.6, 1.8, 
                                                                1.9, 2.8, 1.5, 1.9, 1.9, 1, 1.2, 2.7, 1.9, 1.9, 1.7, 3, 1.5, 
                                                                3.7), f2 = c(1.875, 1.625, 2.5, 1.875, 1.875, 1.375, 1.625, 1.125, 
                                                                             2.625, NA, 1.875, 1.125, 1.5, 1.625, 1.125, 1.125, 2, 3.875, 
                                                                             2.5, 1.875, 1.5, NA, 1.875, 1.625, 2.625, 2, 1.25, 2.25, 2.625, 
                                                                             2, 3.625, 2, 1.75, 2.25, 1.875, 2.5, 3.25, 1.125, 2, 3, 1.75, 
                                                                             NA, 2.125, 1.5, 2.5, 1.625, 2.25, 1.75, 2.875, 1.375, 2.75, 2.25, 
                                                                             1.5, 1.625, 2.625, 1.5, 2.375, 2.25, 1.125, 1.875, 2.75, 1.625, 
                                                                             3.125, 1.25, 2.125, 1.25, 1.875, 2.375, 1.25, 1.75, 2.875, 2.5, 
                                                                             2.25, 2, 2, 1.25, 2.375, 1.5, 1.5, 3.5, 2, 1.375, 1.375, 2, 2.25, 
                                                                             2.5, 2.375, 2.625, 2, 1.125, 1.375, 3.5, 2.25, 3, 1.5, 1.5, 2.625, 
                                                                             1.375, 2.75, 2.375), f3 = c(1.16666666666667, 1.33333333333333, 
                                                                                                         1.5, 1.16666666666667, 1.66666666666667, 3, 3.16666666666667, 
                                                                                                         2, 2.5, NA, 2.16666666666667, 3.16666666666667, 2.83333333333333, 
                                                                                                         1, 1.5, 3.66666666666667, 3, 3, 2.66666666666667, 1.16666666666667, 
                                                                                                         2.33333333333333, NA, 2.16666666666667, 1.66666666666667, 1.83333333333333, 
                                                                                                         2.5, 2.66666666666667, 2.66666666666667, 3.66666666666667, 3.16666666666667, 
                                                                                                         2.66666666666667, 1.16666666666667, 3, 2.5, 1.66666666666667, 
                                                                                                         3.66666666666667, 1.83333333333333, 3, 2.33333333333333, 1.33333333333333, 
                                                                                                         1.83333333333333, NA, 1.5, 1.66666666666667, 2.66666666666667, 
                                                                                                         1.66666666666667, 2.16666666666667, 1.66666666666667, 1.33333333333333, 
                                                                                                         2.16666666666667, 1, 2.5, 1.66666666666667, 2, 3.66666666666667, 
                                                                                                         3.66666666666667, 2.33333333333333, 2.16666666666667, 1, 2.16666666666667, 
                                                                                                         3, 1.33333333333333, 3, 2.16666666666667, 2.66666666666667, 2.16666666666667, 
                                                                                                         4.33333333333333, 2, 1.16666666666667, 3.33333333333333, 1.83333333333333, 
                                                                                                         1.5, 2.16666666666667, 3, 3, 2.16666666666667, 2.83333333333333, 
                                                                                                         1.66666666666667, 2.5, 3.16666666666667, 1.33333333333333, 4.66666666666667, 
                                                                                                         2.16666666666667, 3, 2, 1.5, 1.83333333333333, 3.66666666666667, 
                                                                                                         3, 3.5, 2.16666666666667, 1.66666666666667, 2.66666666666667, 
                                                                                                         4.5, 3, 2.5, 1.33333333333333, 2.16666666666667, 2.66666666666667, 
                                                                                                         3.5)), row.names = c(NA, -100L), class = "data.frame")

标签: rdplyrtidyverse

解决方案


library(purrr)   # for map() and reduce()
library(stringr) # for str_replace()
library(dplyr)   # for select(), left_join(), group_by(), summarise(), ungroup(), mutate_at(), arrange()

# first define the function `fct()` that does the job for one value of "f":
fct <- function(x) {
  items %>% 
    select(id, x) %>% 
    left_join(normative_table, x) %>% 
    select(id, percentile, classification) %>% 
    group_by(id, classification) %>% 
    summarise(percentile = max(percentile)) %>% 
    ungroup() %>% 
    mutate_at("id", as.integer) %>% 
    arrange(id) %>% 
    mutate_at("id", as.character)
}

# then use it for your need:
map(c("f1", "f2", "f3"), f) %>% 
  reduce(left_join, "id") %>% 
  setNames(., names(.) %>%
             str_replace("\\.x", "1") %>% 
             str_replace("\\.y", "2") %>% 
             str_replace("([en])$", "\\13")) %>% 
  left_join(items, .)

您可能可以将map()and替换reduce()map_dfc().


推荐阅读