r - 通过基于多个条件汇总特定列在 R 中创建一个新列
问题描述
我正在尝试创建一个period
从下面的数据框调用的新列
structure(list(fw01 = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3,
24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4,
30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8,
19.7, 15, 21.4), fw02 = c(6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8,
8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4),
fw03 = c(160, 160, 108, 258, 360, 225, 360, 146.7, 140.8,
167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 78.7, 75.7,
71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 351, 145,
301, 121), fw04 = c(110, 110, 93, 110, 175, 105, 245, 62,
95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97,
150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109), fw05 = c(3.9,
3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92,
3.07, 3.07, 3.07, 2.93, 3, 3.23, 4.08, 4.93, 4.22, 3.7, 2.76,
3.15, 3.73, 3.08, 4.08, 4.43, 3.77, 4.22, 3.62, 3.54, 4.11
), fw06 = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19,
3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2,
1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14,
1.513, 3.17, 2.77, 3.57, 2.78), fw07 = c(16.46, 17.02, 18.61,
19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3, 18.9, 17.4, 17.6,
18, 17.98, 17.82, 17.42, 19.47, 18.52, 19.9, 20.01, 16.87,
17.3, 15.41, 17.05, 18.9, 16.7, 16.9, 14.5, 15.5, 14.6, 18.6
), fw08 = c(0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1), fw09 = c(1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1), fw10 = c(4, 4, 4, 3,
3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3,
3, 3, 4, 5, 5, 5, 5, 5, 4), fw11 = c(4, 4, 1, 1, 2, 1, 4,
2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1,
2, 2, 4, 6, 8, 2)), class = "data.frame", row.names = c(NA,
-32L))
这些是我根据要求定义的时期
p1 <- c("fw01","fw02","fw03","fw04")
p2 <- c("fw05","fw06","fw07","fw08")
p3 <- c("fw09","fw10","fw11","fw12","fw13")
p4 <- c("fw14","fw15","fw16","fw17")
p5 <- c("fw18","fw19","fw20","fw21")
p6 <- c("fw22","fw23","fw24","fw25","fw26")
p7 <- c("fw27","fw28","fw29","fw30")
p8 <- c("fw31","fw32","fw33","fw34")
p9 <- c("fw35","fw36","fw37","fw38","fw39")
p10 <- c("fw40","fw41","fw42","fw43")
p11 <- c("fw44","fw45","fw46","fw47")
p12 <- c("fw48","fw49","fw50","fw51","fw52")
我的要求是该period
列应该是第一个周期fw01+fw02+fw03+fw04
的周数的总和,即表的最后一列中的周数是否属于第二个周期,依此类推。在上面的示例中,最后一列是第 11 周(· fw11
),属于第 3 个周期,p3
根据定义的向量。在这种情况下,我希望该period
列是 period2 中周数的总和,即fw05+fw06+fw07+fw08
. 为此,我编写了 2 个不同的逻辑
第一种方法是使用dplyr::case_when
dplyr::mutate(df2,
prev_per = case_when(rev(names(df2))[1] %in% p2 ~ fw01+fw02+fw03+fw04,
rev(names(df2))[1] %in% p3 ~ fw05+fw06+fw07+fw08,
rev(names(df2))[1] %in% p4 ~ fw09+fw10+fw11+fw12+fw13,
rev(names(df2))[1] %in% p5 ~ fw14+fw15+fw16+fw17,
rev(names(df2))[1] %in% p6 ~ fw18+fw19+fw20+fw21,
rev(names(df2))[1] %in% p7 ~ fw22+fw23+fw24+fw25+fw26,
rev(names(df2))[1] %in% p8 ~ fw27+fw28+fw29+fw30,
rev(names(df2))[1] %in% p9 ~ fw31+fw32+fw33+fw34,
rev(names(df2))[1] %in% p10 ~ fw35+fw36+fw37+fw38+fw39,
rev(names(df2))[1] %in% p11 ~ fw40+fw41+fw42+fw43,
rev(names(df2))[1] %in% p12 ~ fw44+fw45+fw46+fw47))
上面的问题是,数据框中根本不存在其他列。理想情况下,条件在第二个case_when
本身得到满足,但操作没有中断,这会导致错误说fw12 not found
第二种方法的示例是使用ifelse
基础包中的函数。
df7<- dplyr::mutate(df2,
prev_per = ifelse(rev(names(df2))[1] %in% p2, fw01+fw02+fw03+fw04,
ifelse(rev(names(df2))[1] %in% p3, fw05+fw06+fw07+fw08,
ifelse(rev(names(df2))[1] %in% p4, fw09+fw10+fw11+fw12+fw13))))
在这里,当条件满足时,操作正常中断,但它在列的所有行中返回相同的数字,period
如下所示
structure(list(fw01 = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3,
24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4,
30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8,
19.7, 15, 21.4), fw02 = c(6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8,
8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4),
fw03 = c(160, 160, 108, 258, 360, 225, 360, 146.7, 140.8,
167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 78.7, 75.7,
71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 351, 145,
301, 121), fw04 = c(110, 110, 93, 110, 175, 105, 245, 62,
95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97,
150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109), fw05 = c(3.9,
3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92,
3.07, 3.07, 3.07, 2.93, 3, 3.23, 4.08, 4.93, 4.22, 3.7, 2.76,
3.15, 3.73, 3.08, 4.08, 4.43, 3.77, 4.22, 3.62, 3.54, 4.11
), fw06 = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19,
3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2,
1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14,
1.513, 3.17, 2.77, 3.57, 2.78), fw07 = c(16.46, 17.02, 18.61,
19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3, 18.9, 17.4, 17.6,
18, 17.98, 17.82, 17.42, 19.47, 18.52, 19.9, 20.01, 16.87,
17.3, 15.41, 17.05, 18.9, 16.7, 16.9, 14.5, 15.5, 14.6, 18.6
), fw08 = c(0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1), fw09 = c(1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1), fw10 = c(4, 4, 4, 3,
3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3,
3, 3, 4, 5, 5, 5, 5, 5, 4), fw11 = c(4, 4, 1, 1, 2, 1, 4,
2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1,
2, 2, 4, 6, 8, 2), prev_per = c(22.98, 22.98, 22.98, 22.98,
22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98,
22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98,
22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98, 22.98,
22.98)), class = "data.frame", row.names = c(NA, -32L))
请建议如何解决此问题。
解决方案
对于一个真正糟糕的解决方案,您可以利用case_when
忽略NULL
输入且if
没有else
will return的事实NULL
。
因此,将条件移入 anif
并遵循 withTRUE
以强制评估。
df %>%
mutate(
prev_per = case_when(
if (rev(names(df))[1] %in% p2) TRUE ~ fw01+fw02+fw03+fw04,
if (rev(names(df))[1] %in% p3) TRUE ~ fw05+fw06+fw07+fw08,
if (rev(names(df))[1] %in% p4) TRUE ~ fw09+fw10+fw11+fw12+fw13,
if (rev(names(df))[1] %in% p5) TRUE ~ fw14+fw15+fw16+fw17,
if (rev(names(df))[1] %in% p6) TRUE ~ fw18+fw19+fw20+fw21
)
)
我讨厌这个答案,但它似乎有效。输出:
fw01 fw02 fw03 fw04 fw05 fw06 fw07 fw08 fw09 fw10 fw11 prev_per
1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 22.980
2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 23.795
3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 25.780
4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 26.735
5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 23.610
推荐阅读
- javascript - 跟踪 alpine.js 中的输入变化
- java - 尝试为 Keycloak 创建自定义身份验证器提供程序时,来自 Maven 部署的 NoClassDefFoundError
- php - php Excel 在 2 个地方下载文件,第一个在 htdocs 和下载文件夹中,如何停止在 htdocs 或服务器上下载文件?
- c - 为什么父级中的 printf() 几乎总是在 fork() 之后赢得竞争条件?
- python-3.x - 如何使用 selenium 在 iframe 中获取 docx?
- postgresql - 如何将 AWS RDS 实例缩减为免费套餐
- powerbi - Power BI 查询编辑器 - 在表底部插入行
- javascript - Next.JS 静态站点生成和客户端 Apollo 获取
- android - 如何在 Android 应用程序运行时修改或添加资源?
- python - 将一列与另一数据框列匹配并粘贴第二个数据中的值 - Python