将 df1 中的行值与 df2 中的列名匹配到 return df2 的相同行值

Match row value in df1 with column name in df2 to return same row value of df2

这个问题类似于我在这里找到的问题:

但我不想匹配行和相乘,而是想将 df1 中的列值与 df2 中的列名匹配,return 新 df3 中 df2 的相应行值。

df1 <- data.frame(V1=c(1:6),V2=c("X3", "X3_8", "NA", "X5", "X4_5", "X3_8"))
df1
    V1 V2
  1 1  X3
  2 2  X3_8
  3 3  NA
  4 4  X5
  5 5  X4_5
  6 6  X3_8

df2 <- data.frame(name=c("John", "Mary", "Joe", "Tim", "Bob", "Pat"),
                  X3=c(0.5, 1.2, 0.75, 3.1, 2.0, 1.1),
                  X5=c(1.0, 2.3, 4.2, 5, 1.1, 3.0),
                  X3_8=c(0.6, 1.0, 2.0, 1.0, 0.7, 1.4),
                  X4_5=c(0.4, 0.3, 3.0, 1.0, 2.0, 0.9))
df2
     name   X3    X5    X3_8  X4_5
  1  John   0.5   1.0   0.6   0.4
  2  Mary   1.2   2.3   1.0   0.3
  3  Joe    0.75  4.2   2.0   3.0
  4  Tim    3.1   5.0   1.0   1.0
  5  Bob    2.0   1.1   0.7   2.0
  6  Pat    1.1   3.0   1.4   0.9

这就是我想要的:

df3 <- data.frame(name=c("John", "Mary", "Joe", "Tim", "Bob", "Pat"),
                  values=c(0.5, 1.0, NA, 5.0, 1.0, 1.4))
    name values
  1 John    0.5
  2 Mary    1.0
  3  Joe     NA
  4  Tim    5.0
  5  Bob    1.0
  6  Pat    1.4      

在我真正的 df1 和 df2 中有 64 行,其中 df1 中的 "V1" 对应于 df2 中 "name" 列的数字索引。在我的 df2 中,有 22 列,即一列带有 "name",另外 21 列带有 "X*" 以匹配 df1 中的 "V2"。我尝试将 "V2" 转换为行名,但这不起作用,因为存在 NA 和重复值。

奖金但不是必需的:我有 10 个 df1 和 10 个 df2,并且需要为每一对 df1 和 df2 执行此操作,其中 df1 和 df2 的名称包含共同的年份。例如,我需要将 df1_2004 与 df2_2004 匹配,创建 df3_2004,然后继续 df1_2005 和 df2_2005,等等。我确信有一种优雅的方法可以在没有 for 循环和 if 语句的情况下执行此操作。

感谢您的帮助。我确定对此有一个简单的基础 R 或 tidyrverse 解决方案,但我正在努力将各个部分组合在一起。原谅我对R中索引的新手理解。

结合将 df2 重塑为长格式和使用 df1 进行左连接,您可以获得所需的结果。

使用:

library(dplyr)
library(tidyr)

df3 <- df1 %>% 
  mutate(name = df2$name[V1]) %>%  # or just mutate(name = df2$name) when the index is equal to the rownumbers
  left_join(., df2 %>% 
              gather(V2, values, -1) %>% 
              group_by(V2) %>% 
              mutate(V1 = row_number()), 
            by = c('V2','V1')) %>% 
  select(name = name.x, values)

给出:

> df3
  name values
1 John    0.5
2 Mary    1.0
3  Joe     NA
4  Tim    5.0
5  Bob    2.0
6  Pat    1.4

世界上功能较少的程序:

n_row <- nrow(df1)
# corce the variable V1 in a factor with the name variables of the
# df2
df1$V1 <- factor(df1$V1, labels = df2$name)
# coerce the variable V2 into a character vector or use 'stringsAsFactors = FALSE' 
# when you read the data frame
df1$V2 <- as.character(df1$V2)
# create a copy of df1 to impute values of the V2 col
df3 <- df1
for (i in 1:n_row) {
  col_index <- which(df1[i, "V2"] == names(df2), arr.ind = TRUE)
  row_index <- which(df1[i, "V1"] == df2$name, arr.ind = TRUE)
  if (length(col_index) == 0) {
    df3[i, "V2"] <- NA
  } else {
    df3[i, "V2"] <- df2[row_index, col_index]
  }
}
names(df3) <- c("name", "values")

给出:

#>df3
   name  values
 1 John  0.5
 2 Mary    1
 3  Joe <NA>
 4  Tim    5
 5  Bob    2
 6  Pat  1.4