【发布时间】:2019-04-02 17:44:27
【问题描述】:
我有一些关于生物体存活率随时间变化的数据。数据是使用每个时间点的许多复制的平均值构建的,这可以产生一个向前的时间步长,增加存活率。有时,这会导致生存率大于 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 with no else),但我还没有找到任何可以有条件地将列中的值更改为前一行中的值的解决方案。任何帮助表示赞赏。
编辑:我意识到mutate 和if_else 在转换值时非常有效。正如我所期望的那样,这些命令不是按顺序从第一个到最后一个替换值,而是同时替换所有值。所以在一系列大于 1 的值中,你会留下一些。因此,如果您只运行命令:
SurvTot1$lx_diag <- if_else(SurvTot1$lx_diag > 1, lag(SurvTot1$lx_diag), SurvTot1$lx_diag)
再一次,你可以去掉 >1 的值。不是最优雅的解决方案,但它确实有效。
【问题讨论】:
-
在
df,Treatment是 0 但在df1,Treatment是 12,怎么办? -
df中的哪一列引用了survivorship? -
@Sonny,
df1中的列是整个数据集的子样本。Generations范围为 0:25。Treatment是第 3 列,范围为 1:4。 Survivorship 是标记为lx和lx_diag的列