这个问题与 this question that I created previously which has an answer 非常相似,但是我开始意识到我试图解决的问题已经发生了变化,我认为我应该重新开始。
我有两个数据框,如下所示:
df1<-structure(list(protocol_no = c("study1", "study2", "study3",
"study4", "study5", "study6", "study7"), status = c("New", "Open",
"Closed", "New", "PI signoff", "Closed", "Open")), row.names = c(NA,
-7L), class = c("tbl_df", "tbl", "data.frame"))
df2<-structure(list(record_id = c(11, 12, 13, 14, 15, 16), protocol_no = c("study1",
"study2", "study3", "study4", "study5", "study6"), status = c("New",
"Closed", "Closed", "New", "PI signoff", "Closed"), form_1_complete = c(0,
0, 0, 0, 0, 0)), row.names = c(NA, 6L), class = "data.frame")
它们几乎引用相同的数据,但 df1 总是较新且具有更多行,而 df2 较旧且具有更多列。此外,它们在现实生活中将有 20,000 多行。
我需要使用 df1 中的新信息更新 df2,这可能意味着需要对新行进行编号(record_id 列),并且可能意味着更新“status”列(如果发生更改)。
例如,在此示例中,study7 的行是新的,需要添加并指定 record_id = 17(因为 16 是该列表停止的位置)。此外,study2 的状态从“关闭”更改为“打开”(在 df1 中为“打开”),因此需要更改。
不起作用的事情:
In the previous solution它使用绑定(bind)行和不同的,但在这种情况下,由于 Study2 已更改并且需要更新,这将绑定(bind) Study2 的两个副本,并且难以区分要删除的副本。
我正在寻找的输出:
包含所有 4 列的数据框,所有内容都有 record_id,每个协议(protocol)一行(“protocol_no”),以及已更改的任何状态已更新以反射(reflect) df1。就像这样:
最佳答案
在这里,加入就足够了
library(data.table)
setDT(df2)[as.data.table(df1), status := i.status, on = .(protocol_no)]
或者使用rows_upsert
并在其他帖子中使用相同的代码
library(dplyr)
library(tidyr)
rows_upsert(df2, df1) %>%
fill(record_id) %>%
mutate(record_id = record_id + (rowid(record_id) - 1))
-输出
record_id protocol_no status form_1_complete
1 11 study1 New 0
2 12 study2 Open 0
3 13 study3 Closed 0
4 14 study4 New 0
5 15 study5 PI signoff 0
6 16 study6 Closed 0
7 17 study7 Open NA
关于R,使用较新的数据更新列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75212823/