将 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
这个问题类似于我在这里找到的问题:
但我不想匹配行和相乘,而是想将 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