【问题标题】:Using Elements of One Dataframe Column to Select Values in Another Dataframe to Create a Third Dataframe Using Tidyverse使用一个数据框列的元素选择另一个数据框中的值以使用 Tidyverse 创建第三个数据框
【发布时间】:2018-01-02 13:42:07
【问题描述】:
library(tidyverse)

下面提供的代码创建了三个数据帧 - Main、LookUp 和 Final。我正在尝试使用 Main 和 LookUp 数据框来创建最终数据框。

例如,Final 表只保留具有 LookUp 表 Section_Lookup 中提供的编号的“Sections”,同时还保留了相应的“Title”变量。

我想尽可能多地使用 tidyverse。我的大部分尝试都是按照下面的代码进行的。我在想,使用两个循环或 purrr 将允许我遍历 Main 和 LookUp 表。这比我通常尝试的更先进,所以我想要一些关于如何继续和处理这种情况的帮助。

New<-map(Main, function(x) {
map(LookUp, function(y) if_else(x$Title1==y$Title_Lookup & ...x$Section1 CONTAINS Y SECTION_LOOKUP... ) )}),

示例代码如下:

主数据框:

    Title1<-c("101A", "101A", "101A", "101A", "101A", "101A", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "400B", "400B", "400B", "400B", "200A", "200A", "250D", "250D", "250D", "250D")
Section1<-c("2A", "2A", "2B", "2B", "2B", "2C", "2A", "2A", "4A", "4A", "4A", "4B", "4B", "4C", "4C", "4C", "4C", "4D", "4D", "2A", "2A", "2B", "2B", "2A", "6A", "1A", "1B", "2A", "2A")
Main<-data_frame(Title1,Section1)

查找表:

Title_Lookup<-c("101A", "203S", "203S", "400B", "200A", "200A", "250D")
Section_Lookup<-c(2, 2, 4, 2, 2, 6, 2)
LookUp<-data_frame(Title_Lookup,Section_Lookup)

最终数据框:

Section_Final<-c("2A", "2B", "2C", "2A", "4A", "4B", "4C", "4D", "2A", "2B", "2A", "6A", "2A")
Title_Final<-c("101A", "101A", "101A", "203S", "203S", "203S", "203S", "203S", "400B", "400B", "200A", "200A", "250D")
Final<-data_frame(Title_Final,Section_Final)

【问题讨论】:

  • 这听起来像是一个先对关键列进行一点清理的连接,但结果似乎是选择每个部分的逻辑让我无法理解
  • 当主数据框只有 1 行 Name1 / 101A 时,输出数据如何有 3 行 Name1 / 101A?
  • 我简化了示例,所以现在只有“标题”和“部分”列。我为过于复杂而道歉。希望你能再看看,仍然帮助我......
  • 我正在根据您之前的示例开发一个答案。现在我的答案看起来“错误”,因为您更改了示例数据集。我稍后会更新我的答案,但以后请避免这种情况。
  • MKR,dplyr 很好! Dplyr 是 tidyverse 的一部分 - 所以 dplyr、tidyr、purrr 等都是我想要的……所以请继续使用 dplyr。

标签: r tidyverse


【解决方案1】:

使用 的解决方案。 str_replace 函数来自,它是 的一部分。如果只想加载 包,可以使用sub("\\D+$", "", Section1) 代替str_replace

library(tidyverse)
Main2 <- Main %>%
  mutate(Number = as.numeric(str_replace(Section1, "\\D+$", ""))) %>%
  semi_join(LookUp, by = c("Title1" = "Title_Lookup",
                           "Number" = "Section_Lookup")) %>%
  select(Title_Final = Title1,  Section_Final = Section1) %>%
  distinct() 
Main2
# # A tibble: 13 x 2
#    Title_Final Section_Final
#    <chr>       <chr>        
#  1 101A        2A           
#  2 101A        2B           
#  3 101A        2C           
#  4 203S        2A           
#  5 203S        4A           
#  6 203S        4B           
#  7 203S        4C           
#  8 203S        4D           
#  9 400B        2A           
# 10 400B        2B           
# 11 200A        2A           
# 12 200A        6A           
# 13 250D        2A  

【讨论】:

  • 感谢您的快速响应,这是一个很好的解决方案!
【解决方案2】:

这是一个基于sqldf包的解决方案,利用charindex()查看Section_Lookup中的字符串是否存在于Section1中。

library(tidyverse)
Title1<-c("101A", "101A", "101A", "101A", "101A", "101A", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "400B", "400B", "400B", "400B", "200A", "200A", "250D", "250D", "250D", "250D")
Section1<-c("2A", "2A", "2B", "2B", "2B", "2C", "2A", "2A", "4A", "4A", "4A", "4B", "4B", "4C", "4C", "4C", "4C", "4D", "4D", "2A", "2A", "2B", "2B", "2A", "6A", "1A", "1B", "2A", "2A")
Main<-data_frame(Title1,Section1)

Title_Lookup<-c("101A", "203S", "203S", "400B", "200A", "200A", "250D")
Section_Lookup<-as.character(c(2, 2, 4, 2, 2, 6, 2))
LookUp<-data_frame(Title_Lookup,Section_Lookup)

sqlQuery <- "select distinct a.Title1 as Title, a.Section1 as Section 
                    from Main as a
             left join LookUp as b 
             where 
             a.Title1 = b.Title_Lookup and
             charindex(b.Section_Lookup,a.Section1) > 0"
sqldf(sqlQuery)

...以及输出。

> sqldf(sqlQuery)
   Title Section
1   101A      2A
2   101A      2B
3   101A      2C
4   203S      2A
5   203S      4A
6   203S      4B
7   203S      4C
8   203S      4D
9   400B      2A
10  400B      2B
11  200A      2A
12  200A      6A
13  250D      2A
>

【讨论】:

    【解决方案3】:

    另一种方法可以基于仅加入Section 列。

    library(dplyr)
    Name1<-c("Name1", "Name2", "Name3", "Name4", "Name5", "Name6", "Name7", "Name8", "Name9",
             "Name10", "Name11", "Name12", "Name13", "Name14", "Name15", "Name16", "Name17",
             "Name18", "Name19", "Name20", "Name21", "Name22", "Name23", "Name24", "Name25",
             "Name26", "Name27", "Name28", "Name29")
    Code<-c(10123, 13432, 34554, 45563, 43666, 54444, 55322, 52111, 33443, 88998, 54554,
            33455, 65889, 88888, 22344, 54455, 66655, 22222, 65564, 77677, 65545, 67765,
            34334, 88789, 76776, 67765, 55555, 65445, 65665)
    Title1<-c("101A", "101A", "101A", "101A", "101A", "101A", "203S", "203S", "203S", "203S",
              "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "203S", "400B",
              "400B", "400B", "400B", "200A", "200A", "250D", "250D", "250D", "250D")
    Section1<-c("2A", "2A", "2B", "2B", "2B", "2C", "2A", "2A", "4A", "4A", "4A", "4B", "4B",
                "4C", "4C", "4C", "4C", "4D", "4D", "2A", "2A", "2B", "2B", "2A", "6A", "1A",
                "1B", "2A", "2A")
    Main<-data_frame(Name1,Code,Title1,Section1)
    
    Title_Lookup<-c("101A", "203S", "203S", "400B", "200A", "200A", "250D")
    Section_Lookup<-c(2, 2, 4, 2, 2, 6, 2)
    LookUp<-data_frame(Title_Lookup,Section_Lookup)
    
    #create data.frame of distinct Sections
    df_sections <- distinct(LookUp, Section_Lookup) %>% as.data.frame()
    
    #Use filter to select those records having matching numeric value in Section
    filter(Main, as.numeric(gsub("([0-9]).*","\\1",Section1)) %in% df$Section_Lookup) %>%
      select(Title1, Section1) %>% distinct()
    
    #The result:
    # A tibble: 13 x 2
       Title1 Section1
        <chr>    <chr>
     1   101A       2A
     2   101A       2B
     3   101A       2C
     4   203S       2A
     5   203S       4A
     6   203S       4B
     7   203S       4C
     8   203S       4D
     9   400B       2A
    10   400B       2B
    11   200A       2A
    12   200A       6A
    13   250D       2A
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 2023-04-09
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      相关资源
      最近更新 更多