jmo*_*gil 5 r lapply dataframe rowsum data.table
我有一个连续年份(列)的独特个体(行)的值数据框架。这里提供了一个虚拟数据示例:
dt = structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), `2015` = c(0,
0.8219178, 0, 0.1369863, 0, 1.369863, 0.2739726, 0.8219178, 5,
0), `2016` = c(0, 1.369863, 0, 0.2739726, 0, 0.2739726, 0, 3.2876712,
0, 0), `2017` = c(0.6849315, 0, 0, 0.6849315, 0, 0.5479452, 0,
0, 0, 0), `2018` = c(1.0958904, 0.5479452, 1.9178082, 0, 0, 0,
0, 0, 0, 3), `2019` = c(0, 0, 0, 1.0958904, 0, 0.9589041, 0.5479452,
0, 0, 0), `2020` = c(0.4383562, 0, 0, 0, 0.2739726, 0.6849315,
0, 0, 0, 0)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-10L))
Run Code Online (Sandbox Code Playgroud)
我想创建一个数据集,其中每年应出现的每个人的最大值为 1。如果超过该值,我想将超出 1 的值带入下一年(列)并将其求和那一年对每个人的价值等等。
预期结果是:
dt_expected = structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), `2015` = c(0,
0.8219178, 0, 0.1369863, 0, 1, 0.2739726, 0.8219178, 1, 0), `2016` = c(0,
1, 0, 0.2739726, 0, 0.6438356, 0, 1, 1, 0), `2017` = c(0.6849315,
0.369863, 0, 0.6849315, 0, 0.5479452, 0, 1, 1, 0), `2018` = c(1,
0.5479452, 1, 0, 0, 0, 0, 1, 1, 1), `2019` = c(0.0958904, 0,
0.9178082, 1, 0, 0.9589041, 0.5479452, 0.2876712, 1, 1), `2020` = c(0.4383562,
0, 0, 0.0958904, 0.2739726, 0.6849315, 0, 0, 0, 1)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -10L))
Run Code Online (Sandbox Code Playgroud)
我完全不知道从哪里开始解决这个问题,所以任何帮助实现这个使用data.table将不胜感激。我唯一的想法是使用条件组件的函数lapply。ifelse那么我应该使用rowSums或Reduce实现跨列转移多余值的结果吗?
Martin Morgan 对data.table的回答的翻译:
for (i in 2:(ncol(dt) - 1)) {
x = dt[[i]]
set(dt, j = i, value = pmin(x, 1))
set(dt, j = i + 1, value = dt[[i + 1L]] + pmax(x - 1, 0))
}
Run Code Online (Sandbox Code Playgroud)
不是特别漂亮或高效,但作为起点,我使用pmin()和pmax()每年(以及随后的一年)迭代更新。pmin(x, 1)当前年份为当前年份与 1 ( )中的最小值;下一年为当前下一年加上上一年的差额 ( pmax(x - 1, 0))
update <- function(df) {
result = df
for (idx in 2:(ncol(df) - 1)) {
x = result[[ idx ]]
result[[ idx ]] = pmin(x, 1)
result[[ idx + 1 ]] = result[[ idx + 1 ]] + pmax(x - 1, 0)
}
result
}
Run Code Online (Sandbox Code Playgroud)
我们有
> all.equal(update(dt), dt_expected)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
我不知道如何将其转换为有效的 data.table 语法,但该函数在 data.table 上“工作” update(as.data.table(dt))。