根据R中的两个标准找到相应的值
Finding the corresponding values based on two criteria in R
我有两个数据框
df1 <- data.frame(Region = c(1:5), Code = c(10,11,12,15,15), date = c("2018-12","2018-11","2019-01","2019-01","2019-02"))
df2 <- data.frame(Code = c(10,11,12,13,14,15,16,17,18,19),"2018-10" = c(50:59),"2018-11" = c(20:29),"2018-12" = c(25:34),"2019-01" = c(32:41),"2019-01" = c(40:49),"2019-02" = c(40:49))
我想将df1$Region对应的值匹配存储到df3中。
结果应该如下所示
df3 <- data.frame(Region = c(1:5),Results=c(25,21,34,45,45))
我们可以使用 row/column
索引来提取值,方法是 match
将 'Code' 列作为行索引,并将 date/column 名称作为行索引两个数据集来获取列索引(不使用任何外部包)
cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code),
match(df1$date,
sub('^X(\d{4})\.', "\1-", names(df2)[-1])))])
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 37
#5 5 45
注意:OP 的 post 中的列名称以 ^X
开头,其格式为 .
而不是 -
,因为它是使用 [= 创建的18=](默认)
如果数据集是用check.names = FALSE
创建的,上述解决方案可以进一步简化
cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code),
match(df1$date, names(df2)[-1]))])
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 37
#5 5 45
更新
如果列名重复并希望根据该信息进行匹配,则
i1 <- duplicated(df1$date)
v1 <- numeric(nrow(df1))
v1[!i1] <- df2[-1][cbind(match(df1$Code[!i1],
df2$Code),match(df1$date[!i1], names(df2)[-1]))]
v1[i1] <- rev(df2[-1])[cbind(match(df1$Code[i1],
df2$Code),match(df1$date[i1], rev(names(df2)[-1])))]
cbind(df1['Region'], Results = v1)
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 45
#5 5 45
注意:没有使用外部包
涉及 dplyr
和 tidyr
的一个选项可能是:
df1 %>%
inner_join(df2 %>%
pivot_longer(-Code), by = c("Code" = "Code",
"date" = "name"))
Region Code date value
1 1 10 2018-12 25
2 2 11 2018-11 21
3 3 12 2019-01 34
4 4 15 2019-01 37
5 5 15 2019-02 45
我认为 df2 中的两列同名是打字错误。
我有两个数据框
df1 <- data.frame(Region = c(1:5), Code = c(10,11,12,15,15), date = c("2018-12","2018-11","2019-01","2019-01","2019-02"))
df2 <- data.frame(Code = c(10,11,12,13,14,15,16,17,18,19),"2018-10" = c(50:59),"2018-11" = c(20:29),"2018-12" = c(25:34),"2019-01" = c(32:41),"2019-01" = c(40:49),"2019-02" = c(40:49))
我想将df1$Region对应的值匹配存储到df3中。
结果应该如下所示
df3 <- data.frame(Region = c(1:5),Results=c(25,21,34,45,45))
我们可以使用 row/column
索引来提取值,方法是 match
将 'Code' 列作为行索引,并将 date/column 名称作为行索引两个数据集来获取列索引(不使用任何外部包)
cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code),
match(df1$date,
sub('^X(\d{4})\.', "\1-", names(df2)[-1])))])
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 37
#5 5 45
注意:OP 的 post 中的列名称以 ^X
开头,其格式为 .
而不是 -
,因为它是使用 [= 创建的18=](默认)
如果数据集是用check.names = FALSE
创建的,上述解决方案可以进一步简化
cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code),
match(df1$date, names(df2)[-1]))])
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 37
#5 5 45
更新
如果列名重复并希望根据该信息进行匹配,则
i1 <- duplicated(df1$date)
v1 <- numeric(nrow(df1))
v1[!i1] <- df2[-1][cbind(match(df1$Code[!i1],
df2$Code),match(df1$date[!i1], names(df2)[-1]))]
v1[i1] <- rev(df2[-1])[cbind(match(df1$Code[i1],
df2$Code),match(df1$date[i1], rev(names(df2)[-1])))]
cbind(df1['Region'], Results = v1)
# Region Results
#1 1 25
#2 2 21
#3 3 34
#4 4 45
#5 5 45
注意:没有使用外部包
涉及 dplyr
和 tidyr
的一个选项可能是:
df1 %>%
inner_join(df2 %>%
pivot_longer(-Code), by = c("Code" = "Code",
"date" = "name"))
Region Code date value
1 1 10 2018-12 25
2 2 11 2018-11 21
3 3 12 2019-01 34
4 4 15 2019-01 37
5 5 15 2019-02 45
我认为 df2 中的两列同名是打字错误。