簡體   English   中英

按順序將 data.frame 中的所有特定值替換為另一個 data.frame 中的值 R

[英]Replace all specific values in data.frame with values from another data.frame sequentially R

我有一個 data.frame (df1),我想為來自另一個 data.frame (df2) 的每個樣本包含一個最近的年齡:

df1$age <- df2$age_9[match(df1$Sample_ID, df2$Sample_ID)]

問題是在 df2 中有 9 列年齡,因為每列表示特定檢查日期的年齡(age_1 是從第一次就診開始,age_9 是第 9 次就診時的年齡)並且患者不會進行所有就診.

如何從非空檢查日期添加最近獲得的年齡?

又名,如果 age_9 == "." 代替 ”。” 與 age_8 那么如果 age_8 == "." 代替 ”。” 與年齡_7 ...等

由此:

View(df1)
Sample Age
1      50
2      .
3      .

至:

View(df1)
Sample Age
1      50
2      49
3      30

從數據df2

View(df2)
Sample Age_1 Age_2 Age_3
1      40    42    44
2      35    49    .
3      30    .     .

這是我的嘗試:

df1$age[which(df1$age == ".")] <- df2$age_8[match(df1$Sample_ID, df2$Sample_ID)]

使用base R ,我們可以使用max.col返回每行的last列索引,其中“年齡”列不是. , cbind與行序列返回行/列索引,提取元素並更改 'df1' 中的 'Age' 列,其中 'Age' 為.

df1$Age <- ifelse(df1$Age == ".", df2[-1][cbind(seq_len(nrow(df2)), 
        max.col(df2[-1] != ".", "last"))], df1$Age)

df1 <- type.convert(df1, as.is = TRUE)

-輸出

df1
#  Sample Age
#1      1  50
#2      2  49
#3      3  30

或通過將tidyverse重塑為“long”格式使用 tidyverse,然后在slice將最后一行按“Sample”分組后進行連接

library(dplyr)
library(tidyr)
df2 %>% 
    mutate(across(starts_with('Age'), as.integer)) %>%
    pivot_longer(cols = starts_with('Age'), values_drop_na = TRUE) %>%
    group_by(Sample) %>% 
    slice_tail(n = 1) %>% 
    ungroup %>% 
    select(-name) %>%
    right_join(df1) %>%
    transmute(Sample, Age = coalesce(as.integer(Age), value))

-輸出

# A tibble: 3 x 2
#  Sample   Age
#   <int> <int>
#1      1    50
#2      2    49
#3      3    30

數據

df1 <- structure(list(Sample = 1:3, Age = c("50", ".", ".")), 
       class = "data.frame",
  row.names = c(NA, 
-3L))

df2 <- structure(list(Sample = 1:3, Age_1 = c(40L, 35L, 30L), Age_2 = c("42", 
"49", "."), Age_3 = c("44", ".", ".")), class = "data.frame", 
row.names = c(NA, 
-3L))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM