繁体   English   中英

R:根据组和条件生成新列

[英]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”的medianelse返回“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM