簡體   English   中英

用r中的先前值替換條件值

[英]Replacing conditional values with previous values in r

我有一些關於生物存活率隨時間變化的數據。 數據是使用每個時間點許多重復樣本的平均值構建的,這可以產生一個向前的時間步,並提高生存率。 有時,這會導致生存率大於1,這是不可能的。 如何在同一列中有條件地將大於1的值更改為之前的值?

數據如下所示:

>df
 Generation Treatment  time    lx
 1 0                  1     0 1    
 2 0                  1     2 1    
 3 0                  1     4 0.970
 4 0                  1     6 0.952
 5 0                  1     8 0.924
 6 0                  1    10 0.913
 7 0                  1    12 0.895
 8 0                  1    14 0.729
 9 0                  2     0 1    
10 0                  2     2 1   

我已經嘗試過像這樣改變感興趣的列,它仍然會產生高於1的值:

df1 <- df %>%
  group_by(Generation, Treatment) %>%
  mutate(lx_diag = as.numeric(lx/lag(lx, default = first(lx)))) %>% #calculate running survival
  mutate(lx_diag = if_else(lx_diag > 1.000000, lag(lx_diag), lx_diag)) #substitute values >1 with previous value

>df1
Generation Treatment  time    lx lx_diag
 1 12                 1     0 1       1    
 2 12                 1     2 1       1    
 3 12                 1     4 1       1    
 4 12                 1     6 0.996   0.996
 5 12                 1     8 0.988   0.992
 6 12                 1    10 0.956   0.968
 7 12                 1    12 0.884   0.925
 8 12                 1    14 0.72    0.814
 9 12                 1    15 0.729   1.01 
10 12                 1    19 0.76    1.04 

我希望結果看起來像:

>df1
Generation Treatment  time    lx lx_diag
 1 12                 1     0 1       1    
 2 12                 1     2 1       1    
 3 12                 1     4 1       1    
 4 12                 1     6 0.996   0.996
 5 12                 1     8 0.988   0.992
 6 12                 1    10 0.956   0.968
 7 12                 1    12 0.884   0.925
 8 12                 1    14 0.72    0.814
 9 12                 1    15 0.729   0.814 
10 12                 1    19 0.76    0.814

我知道您可以有條件地將值更改為特定值(即ifelse,沒有其他設置 ),但是我沒有找到任何可以有條件地將一列中的值更改為上一行中值的解決方案。 任何幫助表示贊賞。

編輯:我認識到mutateif_else在轉換值時非常有效。 這些命令不是像我期望的那樣從頭到尾依次替換值,而是同時替換所有值。 因此,在一系列> 1的值中,您將剩下一些。 因此,如果只運行命令:

SurvTot1$lx_diag <- if_else(SurvTot1$lx_diag > 1, lag(SurvTot1$lx_diag), SurvTot1$lx_diag)

再次,您可以刪除> 1的值。 不是最優雅的解決方案,但它可以工作。

這對我來說似乎是一個非常丑陋的解決方案,但是我什么也沒想到:

df = data.frame(
  "Generation" = rep(12,10),
  "Treatent" = rep(1,10),
  "Time" = c(seq(0,14,by=2),15,19),
  "lx_diag" = c(1,1,1,0.996,0.992,0.968,0.925,0.814,1.04,1.04)
)


update_lag = function(x){
  k <<- k+1
  x
}

k=1

df  %>% 
  mutate(
    lx_diag2 = ifelse(lx_diag <=1,update_lag(lx_diag),lag(lx_diag,n=k))
  )

使用@Fino的數據,這是我使用基數R矢量化解決方案

vals.to.replace <- which(df$lx_diag > 1)
vals.to.substitute <- sapply(vals.to.replace, function(x) tail( df$lx_diag[which(df$lx_diag[1:x] <= 1)], 1) )
df$lx_diag[vals.to.replace] = vals.to.substitute
df

   Generation Treatent Time lx_diag
1          12        1    0   1.000
2          12        1    2   1.000
3          12        1    4   1.000
4          12        1    6   0.996
5          12        1    8   0.992
6          12        1   10   0.968
7          12        1   12   0.925
8          12        1   14   0.814
9          12        1   15   0.814
10         12        1   19   0.814

暫無
暫無

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

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