按 id 合并,但在某些列中用新数据替换旧数据
merge by id but replace old data with new data in some columns
基本上,我有一个数据框,其中有一些数据需要替换为不同数据框中的数据。仅需要更改许多列中的少数几个观察结果。
为了说明,假设我有一个数据框:
df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'),
var1 = c(40, 22, 12, 4, 0),
var2 = c(75, 55, 65, 15, 0),
var3 = c(9, 18, 81, 3, 0),
var4 = c(1, 11, 21, 61, 0),
var5 = c(-1, -2, -3, -4, 0),
var6 = c(0, 1, 0, 1, 0))
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
2 b 22 55 18 11 -2 1
3 c 12 65 81 21 -3 0
4 d 4 15 3 61 -4 1
5. e 0 0 0 0 0 0
然后,一些更好的观察“b”和“c”的数据出现了,但仅限于变量“var2”和“var3”:
df2 <- data.frame(index = c('a', 'b', 'c', 'd'),
var1 = c(40, 22, 12, 4),
var2 = c(75, 550, 650, 15),
var3 = c(9, 180, 810, 3),
var4 = c(1, 11, 21, 61))
index var1 var2 var3 var4
1 a 40 75 9 1
2 b 22 550 180 11
3 c 12 650 810 21
4 d 4 15 3 61
我想要结果数据框:
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
2 b 22 550 180 11 -2 1
3 c 12 650 810 21 -3 0
4 d 4 15 3 61 -4 1
5 e 0 0 0 0 0 0
任何提示(特别是任何可提供的 tidyverse 解决方案?)我玩过 mutate
、across
和 replace
,但似乎无法理解。
澄清:我希望将 var2 和 var3 的新值替换为 df2 中的值,只要在 df1 中找到索引值。其他一切都应该保持不变。我正在处理的数据集的索引值出现了很多次。我尝试了以下,但语法有问题:
df1 %>%
mutate(across(c(var2, var3),
~if_else(index %in% df2$index),
.[df2$index],
.))
更新二:新说明后:删除之前的回答:
library(dplyr)
bind_rows(df1, df2) %>%
arrange(index) %>%
mutate(across(var1:var4, ~ifelse(index=="b" |
index == "c", lead(.), .))) %>%
na.omit()
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
3 b 22 550 180 11 -2 1
5 c 12 650 810 21 -3 0
7 d 4 15 3 61 -4 1
9 e 0 0 0 0 0 0
根据您在 OP 中提供的数据,以及 'better' 观察值较大的事实,以下似乎给出了预期的结果:
library(dplyr)
df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'),
var1 = c(40, 22, 12, 4, 0),
var2 = c(75, 55, 65, 15, 0),
var3 = c(9, 18, 81, 3, 0),
var4 = c(1, 11, 21, 61, 0),
var5 = c(-1, -2, -3, -4, 0),
var6 = c(0, 1, 0, 1, 0))
df2 <- data.frame(index = c('a', 'b', 'c', 'd'),
var1 = c(40, 22, 12, 4),
var2 = c(75, 550, 650, 15),
var3 = c(9, 180, 810, 3),
var4 = c(1, 11, 21, 61))
get_best <- function(col){
value <- max(unlist(col), na.rm=TRUE)
return(value)
}
a <- bind_rows(df1,df2) %>%
group_by(index) %>%
mutate(across(.cols=everything(),
.fns=get_best)) %>%
unique()
输出:
# A tibble: 5 × 7
# Groups: index [5]
index var1 var2 var3 var4 var5 var6
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 a 40 75 9 1 -1 0
2 b 22 550 180 11 -2 1
3 c 12 650 810 21 -3 0
4 d 4 15 3 61 -4 1
5 e 0 0 0 0 0 0
基本上,我有一个数据框,其中有一些数据需要替换为不同数据框中的数据。仅需要更改许多列中的少数几个观察结果。
为了说明,假设我有一个数据框:
df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'),
var1 = c(40, 22, 12, 4, 0),
var2 = c(75, 55, 65, 15, 0),
var3 = c(9, 18, 81, 3, 0),
var4 = c(1, 11, 21, 61, 0),
var5 = c(-1, -2, -3, -4, 0),
var6 = c(0, 1, 0, 1, 0))
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
2 b 22 55 18 11 -2 1
3 c 12 65 81 21 -3 0
4 d 4 15 3 61 -4 1
5. e 0 0 0 0 0 0
然后,一些更好的观察“b”和“c”的数据出现了,但仅限于变量“var2”和“var3”:
df2 <- data.frame(index = c('a', 'b', 'c', 'd'),
var1 = c(40, 22, 12, 4),
var2 = c(75, 550, 650, 15),
var3 = c(9, 180, 810, 3),
var4 = c(1, 11, 21, 61))
index var1 var2 var3 var4
1 a 40 75 9 1
2 b 22 550 180 11
3 c 12 650 810 21
4 d 4 15 3 61
我想要结果数据框:
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
2 b 22 550 180 11 -2 1
3 c 12 650 810 21 -3 0
4 d 4 15 3 61 -4 1
5 e 0 0 0 0 0 0
任何提示(特别是任何可提供的 tidyverse 解决方案?)我玩过 mutate
、across
和 replace
,但似乎无法理解。
澄清:我希望将 var2 和 var3 的新值替换为 df2 中的值,只要在 df1 中找到索引值。其他一切都应该保持不变。我正在处理的数据集的索引值出现了很多次。我尝试了以下,但语法有问题:
df1 %>%
mutate(across(c(var2, var3),
~if_else(index %in% df2$index),
.[df2$index],
.))
更新二:新说明后:删除之前的回答:
library(dplyr)
bind_rows(df1, df2) %>%
arrange(index) %>%
mutate(across(var1:var4, ~ifelse(index=="b" |
index == "c", lead(.), .))) %>%
na.omit()
index var1 var2 var3 var4 var5 var6
1 a 40 75 9 1 -1 0
3 b 22 550 180 11 -2 1
5 c 12 650 810 21 -3 0
7 d 4 15 3 61 -4 1
9 e 0 0 0 0 0 0
根据您在 OP 中提供的数据,以及 'better' 观察值较大的事实,以下似乎给出了预期的结果:
library(dplyr)
df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'),
var1 = c(40, 22, 12, 4, 0),
var2 = c(75, 55, 65, 15, 0),
var3 = c(9, 18, 81, 3, 0),
var4 = c(1, 11, 21, 61, 0),
var5 = c(-1, -2, -3, -4, 0),
var6 = c(0, 1, 0, 1, 0))
df2 <- data.frame(index = c('a', 'b', 'c', 'd'),
var1 = c(40, 22, 12, 4),
var2 = c(75, 550, 650, 15),
var3 = c(9, 180, 810, 3),
var4 = c(1, 11, 21, 61))
get_best <- function(col){
value <- max(unlist(col), na.rm=TRUE)
return(value)
}
a <- bind_rows(df1,df2) %>%
group_by(index) %>%
mutate(across(.cols=everything(),
.fns=get_best)) %>%
unique()
输出:
# A tibble: 5 × 7
# Groups: index [5]
index var1 var2 var3 var4 var5 var6
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 a 40 75 9 1 -1 0
2 b 22 550 180 11 -2 1
3 c 12 650 810 21 -3 0
4 d 4 15 3 61 -4 1
5 e 0 0 0 0 0 0