【问题标题】:Matching a dataset with another dataset and assigning the respective values using R将数据集与另一个数据集匹配并使用 R 分配相应的值
【发布时间】:2019-05-15 04:08:57
【问题描述】:

考虑下面提供的数据集(D1);

------------------
value_1 | value_2
------------------
  0.05  |   0.56
  0.10  |   0.78
  0.80  |   0.98
  0.45  |   1.50
  0.06  |   2.79
------------------

我需要将上面的数据集与下面提供的数据集(D2)进行匹配;

-----------------------------------------------
range_v1 | sd_value_v1 | range_v2 | sd_value_v2
-----------------------------------------------
   0.2   |     1       |   0.50   |     1
   0.4   |     2       |   0.75   |     2
   0.6   |     3       |   0.90   |     3
   0.8   |     4       |   1.50   |     4
   1.0   |     5       |   3.0    |     5
------------------------------------------------

我需要将我的 D1 与 D2 匹配,并相应地为 value_1 和 value_2 分配“sd_value_v1”、“sd_value_v2”。

D2规定的是,如果v1的值小于等于0.2,那么sd_value_v1(1)就赋值给value_1。同样,如果该值小于 0.4 且大于 0.2,则 (2) 的 sd_value_v1 将分配给 value_1 的相应值。

例子:

value_1 = 0.10

然后在与 D2 匹配时,我应该得到 5 的 sd_value_v1。

示例范围(v1 和 v2):

0 到 0.2 --> 1

0.21 到 0.4 --> 2

0.41 到 0.6 --> 3

0.61 到 0.8 --> 4

0.81 到 1.0 --> 5

预期输出:

---------------------------------------------
value_1 | sd_value_v1 | value_2 | sd_value_v2
---------------------------------------------
  0.05  |      1      |   0.56  |     2
  0.10  |      1      |   0.78  |     3
  0.80  |      4      |   0.98  |     4
  0.45  |      3      |   1.50  |     4
  0.06  |      1      |   2.79  |     4
---------------------------------------------

我目前正在使用“R”来解决这个问题。任何输入都会非常有帮助。

【问题讨论】:

    标签: r


    【解决方案1】:

    在基础 R 中,我们可以使用 mapplycut,使用来自 range.. 列的 breaks 和来自 sd.. 列的 labels 来获得 sd_value

    df1[paste0("sd_value", seq_len(ncol(df1)))] <- 
          mapply(function(x, y, z) cut(x, breaks = c(-Inf, y), labels = z), 
          df1, df2[c(TRUE, FALSE)], df2[c(FALSE, TRUE)])
    
    df1
    #  value_1 value_2 sd_value1 sd_value2
    #1    0.05    0.56         1         2
    #2    0.10    0.78         1         3
    #3    0.80    0.98         4         4
    #4    0.45    1.50         3         4
    #5    0.06    2.79         1         5
    

    根据实际df2 中的列分配方式,列的选择可能会有所不同。在显示的示例中,range..sd_value.. 列交替排列,因此我使用 df2[c(TRUE, FALSE)]df2[c(FALSE, TRUE)] 交替选择列。如果实际情况并非如此,您可以使用grep 根据名称获取列索引

    range_cols <- grep("^range", names(df2))
    sd_cols <- grep("^sd", names(df2))
    

    然后在mapply中使用就好

    df1[paste0("sd_value", seq_len(ncol(df1)))] <- 
              mapply(function(x, y, z) cut(x, breaks = c(-Inf, y), labels = z), 
              df1, df2[range_cols], df2[sd_cols])
    

    【讨论】:

      【解决方案2】:

      这是来自tidyverse的方法

      library(tidyverse)
      list(df1, df2[c(1, 3)], df2[c(2, 4)])  %>% 
         pmap(~  ..3[findInterval(..1, ..2, left.open = TRUE)+1]) %>%
         set_names(str_c("sd_value", seq_along(.))) %>%
           bind_cols(df1, .)
      #   value_1 value_2 sd_value1 sd_value2
      #1    0.05    0.56         1         2
      #2    0.10    0.78         1         3
      #3    0.80    0.98         4         4
      #4    0.45    1.50         3         4
      #5    0.06    2.79         1         5
      

      数据

      df1 <- structure(list(value_1 = c(0.05, 0.1, 0.8, 0.45, 0.06), value_2 = c(0.56, 
      0.78, 0.98, 1.5, 2.79)), class = "data.frame", row.names = c(NA, 
      -5L))
      
      df2 <- structure(list(range_v1 = c(0.2, 0.4, 0.6, 0.8, 1), sd_value_v1 = 1:5, 
          range_v2 = c(0.5, 0.75, 0.9, 1.5, 3), sd_value_v2 = 1:5), 
          class = "data.frame", row.names = c(NA, 
      -5L))
      

      【讨论】:

        猜你喜欢
        • 2021-12-24
        • 2023-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多