将变量的多个值与一个值从另一个数据帧匹配

问题描述 投票:0回答:1

我有两个要匹配的数据帧,然后让它根据此匹配返回一个值。

dt1
Name
Matt
John
Steven
Natalie, Nat
Unknown

 dt2
 Names           Grade

Matt              A
John              B
Steven            C
Natalie           D
 Nat              D
Unknown           NA

我想要R做的是将dt1匹配到dt2,然后再返回一个值。我使用了以下代码:

Merge_df$"Match_name" <- ifelse(df1$"Name" %in% df2$"Names","Right Name",ifelse(grepl    ("Unknown", dt1$"Name", ignore.case = FALSE), "Unknown", "NA"))

所需的输出

Merge_df
A
B
C
D
E
Unknown

但是我得到的不是这个。在其中有两个名称的单元格中,它返回NA,因为它不读取两个名称,它只是尝试将整个值与dt2匹配,而dt2当然没有任何值(Natalie和Nat都在一起) 。我希望R读取两个名称,然后查看是否都在dt2中,然后返回文本值“ Right name”。

有什么想法吗?

r matching
1个回答
0
投票

这是一种蛮力方法:

dt1 <- read.table(header=TRUE, stringsAsFactors=FALSE, sep="|", text="
Name
Matt
John
Steven
Natalie, Nat
Unknown")

dt2 <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
Names
Matt
John
Steven
Natalie
Nat
Unknown")

((我应该注意,我仅使用sep="|"来快速获取此示例中的数据。由于其中一个字段中有空格,因此需要sep=的一些替代方案。我也可以使用[ C0]。)

首先,您不确定如何使用逗号分隔的名称。 readLines可以在这里使用:

split

这意味着嵌套的strsplit(dt1$Name, "[ ,]+") # [[1]] # [1] "Matt" # [[2]] # [1] "John" # [[3]] # [1] "Steven" # [[4]] # [1] "Natalie" "Nat" # [[5]] # [1] "Unknown" sapply(strsplit(dt1$Name, "[ ,]+"), function(s) any(s %in% dt2$Names)) # [1] TRUE TRUE TRUE TRUE TRUE 看起来像这样:

ifelse

(并将其分配给列)。

我希望您的问题不再复杂……当我开始嵌套ifelse(grepl("Unknown", dt1$Name, ignore.case = FALSE), "Unknown", ifelse(sapply(strsplit(dt1$Name, "[ ,]+"), function(s) any(s %in% dt2$Names)), "Right Name", "NA")) # [1] "Right Name" "Right Name" "Right Name" "Right Name" "Unknown" 时,我真的在考虑可以用ifelse简化的数据结构。为此,您需要调整merge的形状(嵌入到很长),以便没有逗号分隔的字段。


替代

从数据效率的角度来看,一个单元格中的[[以逗号分隔的

independent类别”可能会令人讨厌。我建议我们展开dt1,以便每行有一个dt1。但是,为了“记住”每个分组的来源,我们将为其分配一个ID。

从那里,合并/加入它们很简单。我将演示如何使用Name,尽管几乎可以直接在base或dplyr中完成相同的步骤。

data.table

这样,如果需要,您可以

选择

根据library(dplyr) library(tidyr) # unnest dt1 <- read.table(header=TRUE, stringsAsFactors=FALSE, sep="|", text=" Name Matt John Steven Natalie, Nat Unknown") dt2 <- read.table(header=TRUE, stringsAsFactors=FALSE, text=" Names Grade Matt A John B Steven C Natalie D Nat D Unknown NA ") dt1 %>% mutate( id = row_number(), Name = strsplit(Name, "[ ,;]+") ) %>% unnest(cols = Name) %>% left_join(dt2, by = c(Name = "Names")) # # A tibble: 6 x 3 # Name id Grade # <chr> <int> <chr> # 1 Matt 1 A # 2 John 2 B # 3 Steven 3 C # 4 Natalie 4 D # 5 Nat 4 D # 6 Unknown 5 <NA> 重新聚合dt1
© www.soinside.com 2019 - 2024. All rights reserved.