我有以下資料框:
library(dplyr)
old_data = data.frame(id = c(1,2,3), var1 = c(11,12,13))
> old_data
id var1
1 1 11
2 2 12
3 3 13
我想用“new_data”中的資料(即id變數匹配的“old_data”中的行)替換“old_data”第二行中的值:
new_data = data.frame(id = c(4,2,5), var1 = c(11,15,13))
> new_data
id var1
1 4 11
2 2 15
3 5 13
使用此處找到的答案(更新 R 中的資料框行),我嘗試使用“dplyr”庫執行此操作:
update = old_data %>%
rows_update(new_data, by = "id")
但這給了我以下錯誤:
Error: Attempting to update missing rows.
Run `rlang::last_error()` to see where the error occurred.
這就是我想要得到的:
id var1
1 1 11
2 2 15
3 3 13
有人可以告訴我我做錯了什么嗎?
謝謝!
uj5u.com熱心網友回復:
有點亂,但這有效(至少在此示例資料上)
old_data %>%
left_join(new_data,by="id") %>%
mutate(var1 = if_else(!is.na(var1.y),var1.y,var1.x)) %>%
select(id,var1)
# id var1
#1 1 11
#2 2 15
#3 3 13
uj5u.com熱心網友回復:
使用的基本 R 方法match-
inds <- match(old_data$id, new_data$id)
old_data$var1[!is.na(inds)] <- na.omit(new_data$var1[inds])
old_data
# id var1
#1 1 11
#2 2 15
#3 3 13
uj5u.com熱心網友回復:
一種data.table方法(將資料表轉回資料框):
library(data.table)
as.data.frame(setDT(old_data)[new_data, var1 := .(i.var1), on = "id"])
輸出
id var1
1 1 11
2 2 15
3 3 13
另一種tidyverse使用選項rows_update。您可以過濾new_data為僅包含id出現在old_data. 然后,您可以更新這些值,就像您之前嘗試過的那樣。本質上,new_data必須只有id出現在old_data.
library(tidyverse)
old_data %>%
rows_update(., new_data %>% filter(id %in% old_data$id), by = "id")
資料
old_data <-
structure(list(id = c(1, 2, 3), var1 = c(11, 12, 13)),
class = "data.frame",
row.names = c(NA,-3L))
new_data <-
structure(list(id = c(4, 2, 5), var1 = c(11, 15, 13)),
class = "data.frame",
row.names = c(NA,-3L))
uj5u.com熱心網友回復:
我們可以使用dplyr::rows_updateif 我們首先使用semi_joinonnew_data僅過濾id包含在old_data.
library(dplyr)
old_data %>%
rows_update(new_data %>%
semi_join(old_data, by = "id"),
by = "id")
#> id var1
#> 1 1 11
#> 2 2 15
#> 3 3 13
由reprex 包(v0.3.0)于 2021 年 12 月 29 日創建
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/397041.html
上一篇:以天為單位計算暴露時間
下一篇:如何使用字串的多個條件過濾行
