以编程方式查找,更正具有不同列和行长度的数据帧中的ID

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以编程方式查找,更正具有不同列和行长度的数据帧中的ID相关的知识,希望对你有一定的参考价值。

我有两个不同长度和宽度的数据帧。两者都包含多年来网站上的面板数据,每个网站都有唯一的ID代码。但是,这些唯一的ID代码在数据帧之间的某些站点被更改。例如:

Year <- c(2006,2006,2006,2006)
Name <- as.character(c("A","B","C","D.B"))
Qtr.2 <- as.numeric(c(14,32,62,40))
Code <- as.character(c(123,456,789,101))
DF1 <- data.frame(Year,Name,Qtr.2,Code,stringsAsFactors = FALSE)

Year2 <- c(2007,2007,2007,2007,2007,2007)
Name2 <- as.character(c("A","B","C","E","D.B","D.A"))
Qtr.3 <- as.numeric(c(14,32,62,11,40,20))
Code2 <- as.character(c("W33","456","789","121","W133","W111"))
Type <- as.character(c("Blue","Red","Red","Green","Blue","Red"))
DF2 <- data.frame(Year2,Name2,Qtr.3,Code2,Type,stringsAsFactors = FALSE)

> DF1
     Year Name Qtr.2 Code
   1 2006    A    14  123
   2 2006    B    32  456
   3 2006    C    62  789
   4 2006  D.B    40  101

> DF2
    Year2 Name2 Qtr.3 Code2 Type
  1  2007     A    14   W33  Blue
  2  2007     B    32   456   Red
  3  2007     C    62   789   Red
  4  2007     E    11   121 Green
  5  2007   D.B    40  W133  Blue
  6  2007   D.A    20  W111   Red

这里,站点“A”代码已从DF1中的“123”变为DF2中的“W33”。我无法以编程方式查找和转换更改的ID代码以匹配其先前的ID代码。换句话说,我想匹配DF1到DF2的名称,并在发现匹配名称时将DF2中的“Code2”替换为DF1中的“Code”。到目前为止,我的方法涉及一个相当复杂的填充和循环过程。但是,我觉得这必须是一个半规则的争论问题,必须有一个更简单的方法。

理想情况下,我的第二个DF看起来如下:

Year2_fixed <- c(2007,2007,2007,2007,2007,2007)
Name2_fixed <- as.character(c("A","B","C","E","D.B","D.A"))
Qtr.3_fixed <- as.numeric(c(14,32,62,11,40,20))
Code2_fixed <- as.character(c("123","456","789","121","101","W111"))
Type <- as.character(c("Blue","Red","Red","Green","Blue","Red"))
DF2_fixed <-data.frame(Year2_fixed,Name2_fixed,Qtr.3_fixed,Code2_fixed,Type,stringsAsFactors = FALSE)    

> DF2_fixed

    Year2_fixed Name2_fixed Qtr.3_fixed Code2_fixed  Type
  1        2007           A          14         123  Blue
  2        2007           B          32         456   Red
  3        2007           C          62         789   Red
  4        2007           E          11         121 Green
  5        2007         D.B          40         101  Blue
  6        2007         D.A          20         W111  Red

我做了一些看,但我没有找到一个明确的答案在操作系统上解决这个问题。我有可能在搜索中没有明确地提出这个问题。请指出它是否在那里,或者让我知道我是否可以澄清我的问题。

最后几点:我希望能够通过代码执行inner_join,保留两组中出现的观察结果。我提供了一个玩具示例,但是,通常情况下,真正的问题是太大而无法手动检查这些名称。

编辑正如其他人所指出的,已添加stringAsFactors = FALSE以防止出错。

答案

尝试使用match命令:

DF2 <- within(DF2, {
  ind <- match(Name2, DF1$Name)
  new_code <- DF1$Code[ind]
  Code_fixed <- ifelse(is.na(ind), as.character(Code2), as.character(new_code))
  rm(ind, new_code)
})
DF2
另一答案

解决方案是使用dplyr::coalesceleft_join来获得所需的结果。

library(dplyr)

DF2 %>% left_join(select(DF1, Name, Code), by=c("Name2" = "Name")) %>%
  mutate(Code2 = coalesce(Code, Code2)) %>%
  select(-Code)

#   Year2 Name2 Qtr.3 Code2  Type
# 1  2007     A    14   123  Blue
# 2  2007     B    32   456   Red
# 3  2007     C    62   789   Red
# 4  2007     E    11   121 Green
# 5  2007   D.B    40   101  Blue
# 6  2007   D.A    20  W111   Red

注意:在OP的代码中添加了stringsAsFactors = FALSE来创建data.frames,否则会产生不必要的警告。

数据:

Year <- c(2006,2006,2006,2006)
Name <- as.character(c("A","B","C","D.B"))
Qtr.2 <- as.numeric(c(14,32,62,40))
Code <- as.character(c(123,456,789,101))
DF1 <- data.frame(Year,Name,Qtr.2,Code, stringsAsFactors = FALSE)

Year2 <- c(2007,2007,2007,2007,2007,2007)
Name2 <- as.character(c("A","B","C","E","D.B","D.A"))
Qtr.3 <- as.numeric(c(14,32,62,11,40,20))
Code2 <- as.character(c("W33","456","789","121","W133","W111"))
Type <- as.character(c("Blue","Red","Red","Green","Blue","Red"))
DF2 <- data.frame(Year2,Name2,Qtr.3,Code2,Type, stringsAsFactors = FALSE)

以上是关于以编程方式查找,更正具有不同列和行长度的数据帧中的ID的主要内容,如果未能解决你的问题,请参考以下文章

SQL查询以查找列和行中的最大值

Kendo Grid - 查找单击单元格的列和行索引

使用 SSE 和 AVX 查找矩阵中的最大元素及其列和行索引

以“错误”的方式呈现表格:转置列和行?

重新排序矩阵元素以反映朴素python中的列和行聚类

切换数据框中的列和行,并在单独的列标题下列出观察结果以执行 Anova:单因素