行的复杂条件删除/提取

时间:2016-01-25 11:32:22

标签: r

我有一个数据框,我希望运行一些复杂的'if'语句。

提供一些背景信息 - 这是欧盟不同地区的数据。我想在“结果”中查看国家/地区的变化。在欧盟,我们有不同级别的行政边界(表中称为“区域”) - 1和2(表中的“级别”)。我希望探索级别'1'的变异性,但是一些国家的人口较少,因此我必须考虑第2级的变异性。我创建了一个缩短的数据集来说明我的观点。

df >- structure(list(region = structure(c(2L, 4L, 6L, 8L, 9L, 13L, 
16L, 17L, 18L, 21L, 23L, 26L, 27L, 33L, 34L, 41L, 37L, 43L, 48L, 
50L, 56L, 54L, 59L, 3L, 1L, 7L, 5L, 10L, 11L, 12L, 14L, 15L, 
20L, 19L, 22L, 24L, 25L, 28L, 29L, 30L, 31L, 32L, 35L, 36L, 42L, 
38L, 40L, 39L, 45L, 44L, 46L, 49L, 51L, 47L, 52L, 53L, 57L, 58L, 
55L, 61L, 60L), .Label = c("AT13", "AT2", "AT22", "AT3", "BE10", 
"BE2", "BE21", "BE3", "CH0", "CH01", "CH02", "CH03", "CZ0", "CZ01", 
"CZ02", "DE4", "DEC", "DK0", "DK02", "DK04", "EE0", "EE00", "FI1", 
"FI19", "FI1D", "FI2", "FR1", "FR10", "FR21", "FR22", "FR23", 
"FR24", "FR8", "IE0", "IE01", "IE02", "NL1", "NL23", "NL31", 
"NL33", "NL4", "NL41", "NO0", "NO01", "NO03", "NO07", "PL11", 
"PL2", "PL21", "PL3", "PL41", "PL52", "PL62", "SE1", "SE11", 
"SE2", "SE22", "SE32", "SI0", "SI01", "SI02"), class = "factor"), 
    result = c(24.43, 20.37, 23.53, 25.51, 17.73, 30.61, 46.2, 
    43.75, 25.32, 53.32, 34.25, 46.15, 34.59, 38.06, 18.6, 32.29, 
    28.57, 22.36, 40.98, 34.53, 21.09, 23.89, 43.15, 25.73, 30.06, 
    26.64, 16.78, 18.75, 17.51, 19.58, 28.63, 25.44, 24.29, 30.73, 
    53.32, 37.31, 38.19, 34.59, 53.33, 39.02, 22.92, 35.44, 19.07, 
    18.38, 29.26, 38.6, 31.51, 21.54, 22.93, 17.86, 30.77, 39.87, 
    44.7, 36.8, 37.5, 33.33, 19.05, 30.77, 17.98, 39.71, 45.66
    ), level = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L), country = structure(c(1L, 1L, 2L, 2L, 
    3L, 4L, 5L, 5L, 6L, 7L, 8L, 8L, 9L, 9L, 10L, 11L, 11L, 12L, 
    13L, 13L, 14L, 14L, 15L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 4L, 
    4L, 6L, 6L, 7L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 11L, 
    11L, 11L, 11L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 14L, 
    14L, 14L, 15L, 15L), .Label = c("AT", "BE", "CH", "CZ", "DE", 
    "DK", "EE", "FI", "FR", "IE", "NL", "NO", "PL", "SE", "SI"
    ), class = "factor")), .Names = c("region", "result", "level", 
"country"), class = "data.frame", row.names = c(NA, -61L))

所以,

  1. 我想要if语句删除行IF级别= 1并且只有一个国家/地区的级别为1的记录(即它将删除国家CH,CZ,DK,EE,IE,NO和SI )。 (因此将删除第5,6,9,10,15,18和23行) 然后:

  2. 我想要第二个if语句删除行IF级别== 2并且国家IS在级别1的数据框中表示(已应用语句1)。

  3. 如果声明我可以做简单的调节:

    df<-nuts1_2[!(df$level==1),]
    

    ......但我在第二部分上挣扎(即,坚果1 $ $等级== 1&amp; df $ country'只出现一次'??)

    我应该留下一个数据框,详情如下:

           region result level country
    1     AT2  24.43     1      AT
    2     AT3  20.37     1      AT
    3     BE2  23.53     1      BE
    4     BE3  25.51     1      BE
    5     DE4  46.20     1      DE
    6     DEC  43.75     1      DE
    7     FI1  34.25     1      FI
    8     FI2  46.15     1      FI
    9     FR1  34.59     1      FR
    10    FR8  38.06     1      FR
    11    NL4  32.29     1      NL
    12    NL1  28.57     1      NL
    13    PL2  40.98     1      PL
    14    PL3  34.53     1      PL
    15    SE2  21.09     1      SE
    16    SE1  23.89     1      SE
    17   CH01  18.75     2      CH
    18   CH02  17.51     2      CH
    19   CH03  19.58     2      CH
    20   CZ01  28.63     2      CZ
    21   CZ02  25.44     2      CZ
    22   DK04  24.29     2      DK
    23   DK02  30.73     2      DK
    24   EE00  53.32     2      EE
    25   IE01  19.07     2      IE
    26   IE02  18.38     2      IE
    27   NO03  22.93     2      NO
    28   NO01  17.86     2      NO
    29   NO07  30.77     2      NO
    30   SI02  39.71     2      SI
    31   SI01  45.66     2      SI
    

    在一个理想的世界中,如果这些行可以成为另一个名为“已删除”的数据框的子集 - 这将有助于我的记录保存。

    感谢上述任何帮助。

2 个答案:

答案 0 :(得分:3)

使用包可以执行以下操作:

library(data.table)
setDT(df1)[, if(!(level==1 & .N==1)) .SD, by = .(country,level)
           ][, unlev := uniqueN(level), by = country
             ][!(unlev==2 & level==2)][,unlev:=NULL][]

给出:

    country level region result
 1:      AT     1    AT2  24.43
 2:      AT     1    AT3  20.37
 3:      BE     1    BE2  23.53
 4:      BE     1    BE3  25.51
 5:      DE     1    DE4  46.20
 6:      DE     1    DEC  43.75
 7:      FI     1    FI1  34.25
 8:      FI     1    FI2  46.15
 9:      FR     1    FR1  34.59
10:      FR     1    FR8  38.06
11:      NL     1    NL4  32.29
12:      NL     1    NL1  28.57
13:      PL     1    PL2  40.98
14:      PL     1    PL3  34.53
15:      SE     1    SE2  21.09
16:      SE     1    SE1  23.89
17:      CH     2   CH01  18.75
18:      CH     2   CH02  17.51
19:      CH     2   CH03  19.58
20:      CZ     2   CZ01  28.63
21:      CZ     2   CZ02  25.44
22:      DK     2   DK04  24.29
23:      DK     2   DK02  30.73
24:      EE     2   EE00  53.32
25:      IE     2   IE01  19.07
26:      IE     2   IE02  18.38
27:      NO     2   NO03  22.93
28:      NO     2   NO01  17.86
29:      NO     2   NO07  30.77
30:      SI     2   SI02  39.71
31:      SI     2   SI01  45.66

您可以使用

应用相同的逻辑
library(dplyr)
df1 %>% 
  group_by(country,level) %>% 
  mutate(n = n()) %>% 
  filter(!(level==1 & n==1)) %>%
  group_by(country) %>%
  mutate(unlev = length(unique(level))) %>%
  filter(!(unlev==2 & level==2)) %>%
  select(-n, -unlev)

答案 1 :(得分:2)

我们可以使用dplyr

library(dplyr)
df %>%
   group_by(country,level) %>%
   filter(!(level==1 & n()==1)) %>%
   group_by(country) %>% 
   filter(!(n_distinct(level)==2 & level==2)) %>%
   as.data.frame()
#    region result level country
#1     AT2  24.43     1      AT
#2     AT3  20.37     1      AT
#3     BE2  23.53     1      BE
#4     BE3  25.51     1      BE
#5     DE4  46.20     1      DE
#6     DEC  43.75     1      DE
#7     FI1  34.25     1      FI
#8     FI2  46.15     1      FI
#9     FR1  34.59     1      FR
#10    FR8  38.06     1      FR
#11    NL4  32.29     1      NL
#12    NL1  28.57     1      NL
#13    PL2  40.98     1      PL
#14    PL3  34.53     1      PL
#15    SE2  21.09     1      SE
#16    SE1  23.89     1      SE
#17   CH01  18.75     2      CH
#18   CH02  17.51     2      CH
#19   CH03  19.58     2      CH
#20   CZ01  28.63     2      CZ
#21   CZ02  25.44     2      CZ
#22   DK04  24.29     2      DK
#23   DK02  30.73     2      DK
#24   EE00  53.32     2      EE
#25   IE01  19.07     2      IE
#26   IE02  18.38     2      IE
#27   NO03  22.93     2      NO
#28   NO01  17.86     2      NO
#29   NO07  30.77     2      NO
#30   SI02  39.71     2      SI
#31   SI01  45.66     2      SI