根据多个条件选择行

时间:2018-03-02 15:29:13

标签: r if-statement dplyr data.table

我有一个df

  4.56, 3.41, 0.82, 2.31, 3.75, 4.75, 1.22, 2.98, 1.17

这是一个有9个位置的数据框。对于每个位置,我有9个月,每个月有一个x值。

对于每个位置,我想根据以下标准选择一个月:

1)检查哪个月(不包括第9个月)有x> 1,然后选择最接近第9个月的月份。    例如,如果对于位置1,则x的值为

  0.8, 0.6, 0.95, 0.4, 0.88, 0.7, 0.6, 0.45, 0.3

然后第1,2,4,5,6,7,8个月有x> 1从这几个月开始,第8个月最接近第9个月。因此将选择第8个月

2)如果没有一个月有x> 1,只需选择具有最高x值的月份。例如:

如果是某个地点,则x为

  library(dplyr)
  df %>% filter(month != 9) %>% # removes the 9 month so that only the 8 months are evaluated 
        group_by(loc.id) %>% 
        mutate(select.month = x > 1) %>% # mark those months where x > 1
        filter(select.month == TRUE) %>% # select those months where x > 1 is true
        mutate(dif = 9 - month) %>%# subtract each month from 9 to check which one is closest to 9
        summarise(month.id = min(dif)) # select the months which is closest to month 9

然后将选择第3个月(x = 0.95)

我试过了:

jq

但是,在上述功能中,我无法检查所有月份的所有位置 值小于1.我的问题是,当x中没有一个>时,如何更改上面的代码以检查条件2。 1

4 个答案:

答案 0 :(得分:1)

set.seed(123)
> df <- data.frame(loc.id = rep(1:9, each = 9), month = rep(1:9,times = 9), 
                  x = runif(81, min = 0, max = 5))
> set.seed(123)
> df=rbind(df,cbind(loc.id=10,month=1:9 , x=runif(9)))




> df%>%group_by(loc.id)%>%mutate(x=replace(x,9,0),y=cumsum(x>1))%>%
+     summarise(y=ifelse(all(!y),which.max(x),which.max(y)))
# A tibble: 10 x 2
   loc.id     y
    <dbl> <int>
 1      1     8
 2      2     8
 3      3     8
 4      4     7
 5      5     8
 6      6     8
 7      7     7
 8      8     8
 9      9     7
10     10     5

答案 1 :(得分:1)

我稍微修改了你的数据框,因为没有loc.id s只有少数只有少于1的月份。

df %>% 
  group_by(loc.id) %>%
  filter(month != 9) %>% 
  mutate(all_x_less_1 = all(x < 1)) %>% 
  filter(all_x_less_1 | x > 1) %>% 
  filter(month == if_else(all_x_less_1, month[which.max(x)], month[which.min(9 - month)]))

# A tibble: 9 x 4
# Groups:   loc.id [9]
#   loc.id month     x all_x_less_1
#    <int> <int> <dbl> <lgl>       
# 1      1     8 4.46  F           
# 2      2     7 2.25  F           
# 3      3     8 1.18  F           
# 4      4     5 1.13  F           
# 5      5     1 0.758 T           
# 6      6     5 0.715 T           
# 7      7     5 0.639 T           
# 8      8     2 0.509 T           
# 9      9     1 0.395 T         

诀窍是不仅要过滤x < 1,还要过滤x中的loc.id是否小于1.然后if_else调用{ {1}}您可以根据所有filter是否小于1来指定您的条件。

数据

x

答案 2 :(得分:1)

library(data.table)
setDT(d)
d[ , {
  ix <- x > 1 & month != 9 
  .(month = if(any(ix)) last(month[ix]) else month[which.max(x)])
}, by = loc.id]

说明:

对于每个组(by = loc.id),获取索引,其中x&gt; 1,不包括第9个月(x > 1 & month != 9)。如果任何此类索引为真(if(any(ix))),请选择其中的最后一个月(last(month[ix]))。否则选择对应于max x(else month[which.max(x)])的月份。

答案 3 :(得分:0)

一个可能的解决方案是ifelse,如果位置8> 1.0,那么位置8,否则排除第9行后该行的最大值。

一个月的例子:

month1 <- filter(df, loc.id == 1) month1 <- month1[1:8, ] df1 <- ifelse(month1[8,3] > 1.0, month1[8,3], max(month1$x))