[英]R: generate a new column based on groups and conditions
我有一个包含 4 列的数据框(其中的一部分如下所示)。
第一列显示按数字排序的组:1, 2, ....
我想生成一个新列“value4”。 对于每个组,如果组大小大于 2 (>=3),并且“value1”列中的所有值都大于 2 (>2) 或小于 -2 (< -2),则计算“value3”列中的相应值并将其放入该组每一行的“value4”列中。 否则,将“value2”中的值带到“value4”列。
g value1 value2 value3
1 1.1 8 1
1 1.2 8 1
1 1.3 9 1
2 3 10 5
2 4 11 5
2 5 0 4
2 6 1 6
3 -3 2 5
3 -4 3 10
3 -5 4 0
4 -3 1 0
4 -4 1 0
输出将是:
g value1 value2 value3 value4
1 1.1 8 1 8 # for group "1", all the values in "value1" are <2, so the values from column "value2" are taken
1 1.2 8 1 8
1 1.3 9 1 9
2 3 10 5 5 # for group "2", all the values in "value1" are >2, median of numbers 5,5,4,6 from column "value3" is calculated
2 4 11 5 5
2 5 0 4 5
2 6 1 6 5
3 -3 2 5 5 # for group "3", all the values in "value1" are < -2, median of numbers 5,10,0 from column "value3" is calculated
3 -4 3 10 5
3 -5 4 0 5
4 -3 1 0 1 # group size less than 3, so the values from column "value2" are taken
4 -4 1 0 1
我想我可以使用aggregate(),但我不知道如何整合条件。 我感谢您的时间和帮助。
基于条件,我们可以使用if/else
条件,利用 groupsize ( n()
),如果all
value1 小于 -2 或大于 2,则获取“value3”的median
, else
返回“value2”
library(dplyr)
df1 %>%
group_by(g) %>%
mutate(value4 = if(n() > 2 & (all(value1 > 2)| all(value1 < -2))) median(value3)
else value2)
# A tibble: 12 x 5
# Groups: g [4]
# g value1 value2 value3 value4
# <int> <dbl> <int> <int> <dbl>
# 1 1 1.1 8 1 8
# 2 1 1.2 8 1 8
# 3 1 1.3 9 1 9
# 4 2 3 10 5 5
# 5 2 4 11 5 5
# 6 2 5 0 4 5
# 7 2 6 1 6 5
# 8 3 -3 2 5 5
# 9 3 -4 3 10 5
#10 3 -5 4 0 5
#11 4 -3 1 0 1
#12 4 -4 1 0 1
df1 <- structure(list(g = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L,
4L, 4L), value1 = c(1.1, 1.2, 1.3, 3, 4, 5, 6, -3, -4, -5, -3,
-4), value2 = c(8L, 8L, 9L, 10L, 11L, 0L, 1L, 2L, 3L, 4L, 1L,
1L), value3 = c(1L, 1L, 1L, 5L, 5L, 4L, 6L, 5L, 10L, 0L, 0L,
0L)), class = "data.frame", row.names = c(NA, -12L))
您可以使用包data.table
如下:
library(data.table)
setDT(df)[, value4 := if(.N > 2 & (all(value1 > 2) | all(value1 < -2))) median(value3) else value2, g]
这是case_when()的理想情况。*
您希望根据以下条件计算value4
:
如果组大小 > 2并且组中所有value1
的绝对值 > 2 => 取value3
的中位数。 否则使用value2
library(dplyr)
df %>%
group_by(g) %>%
mutate(value4 = case_when( (n() > 2) & (all(abs(value1) > 2)) ~ median(value3),
T ~ value2)
*有人会认为我们可以在这里使用if_else()
因为只有一个条件,但由于某种原因,在条件中使用all()
时它失败了。 我认为它正在返回多个值? 不清楚,但也许其他人可以解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.