Cannot select rows with 0 in a column and values different from 0 in another, in skimr summary

时间:2018-02-01 18:08:20

标签: r dplyr skimr

I have the following data set (simplified with respect to the real one):

foo <- structure(list(id = c(1L, 1L, 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, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L), t = c(67L, 41L, 180L, 73L, 9L, 19L, 83L, 36L, 64L, 57L, 
29L, 137L, 166L, 8L, 177L, 94L, 112L, 101L, 168L, 85L, 53L, 174L, 
120L, 40L, 161L, 72L, 147L, 128L, 94L, 193L, 89L, 201L, 195L, 
13L, 248L, 122L, 120L, 44L, 270L, 134L, 146L, 237L, 105L, 176L, 
97L, 181L, 140L, 99L, 249L, 143L, 79L, 43L, 68L, 90L, 125L, 97L, 
147L, 56L, 52L, 89L, 158L, 31L, 72L, 38L, 50L, 141L, 60L, 126L, 
100L, 66L, 78L, 160L, 118L, 163L, 64L), op1 = c(0.0016, 0.0033, 
-0.0024, -0.0012, 8e-04, 0.0032, 4e-04, -4e-04, 0.0017, -0.0033, 
0.0012, -0.0011, -0.0022, -0.0034, -0.0038, -0.0021, 5e-04, 0.0012, 
-0.0043, 0.0025, 0.0021, -1e-04, -0.0024, 0, 8e-04, -7e-04, 4e-04, 
-8e-04, 0, -0.0021, 0.0017, 0.0021, -0.0026, 7e-04, 0.0048, 0.0011, 
-1e-04, 3e-04, 5e-04, 0.0026, 0.0043, 0.0027, -0.005, -0.001, 
8e-04, 3e-04, 0.0014, -0.0034, 0.0013, 1e-04, 6e-04, 0.0044, 
0.0034, -8e-04, -7e-04, 8e-04, 0.0023, -1e-04, 0.0042, 6e-04, 
-3e-04, 0.0039, -0.0014, 6e-04, 0.0012, 0.0025, 0.0011, 0.0013, 
8e-04, -3e-04, -3e-04, 0.0058, 4e-04, -0.0016, 4e-04), op2 = c(-4e-04, 
4e-04, 0, -2e-04, 1e-04, -3e-04, 5e-04, -2e-04, 2e-04, 0, -1e-04, 
0, -3e-04, 3e-04, -3e-04, 2e-04, 3e-04, 3e-04, 2e-04, 3e-04, 
-1e-04, -2e-04, 5e-04, -4e-04, 1e-04, -1e-04, -1e-04, 0, 5e-04, 
-3e-04, 5e-04, 2e-04, 4e-04, 5e-04, 1e-04, 3e-04, 4e-04, 3e-04, 
-2e-04, 1e-04, -1e-04, 4e-04, 4e-04, -4e-04, 1e-04, -2e-04, -1e-04, 
-4e-04, -4e-04, 4e-04, 4e-04, -3e-04, -2e-04, -2e-04, 2e-04, 
-5e-04, 1e-04, -2e-04, 0, 4e-04, -3e-04, 1e-04, -2e-04, 1e-04, 
-4e-04, 3e-04, 3e-04, 4e-04, -4e-04, 0, -5e-04, 2e-04, 0, 0, 
1e-04), op3 = c(100, 100, 100, 100, 100, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
100), s2 = c(642.33, 642.4, 643.58, 642.29, 642.12, 641.79, 642.66, 
642.54, 642.23, 642.13, 641.91, 642.43, 643.34, 642.56, 643.79, 
642.45, 642.66, 642.75, 642.68, 642.28, 642.61, 642.64, 642.81, 
642.24, 643, 642.48, 642.27, 641.54, 642.1, 642.13, 641.95, 642.31, 
643.24, 641.78, 643.06, 642.08, 642.01, 642.01, 643.12, 642.76, 
642.52, 643.14, 641.94, 642.32, 642.04, 642.01, 642.29, 642.04, 
643.79, 642.31, 642.31, 642.58, 642.94, 642.36, 642.82, 642.94, 
643.07, 642.73, 642.29, 642.33, 643.19, 642.33, 642.25, 641.72, 
642.51, 643.08, 641.8, 642.76, 642.29, 642.25, 642.43, 642.48, 
642.26, 643, 642.53), s6 = c(21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.6, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.6, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 
21.61, 21.61, 21.61, 21.61, 21.61, 21.61, 21.61), s10 = c(1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 
1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3), s18 = c(2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 2388L, 
2388L, 2388L)), class = "data.frame", .Names = c("id", "t", "op1", 
"op2", "op3", "s2", "s6", "s10", "s18"), row.names = c(NA, -75L
))

I want to filter the variables with a 0 value of the standard deviation and a non-zero values of the IQR (interquartile range) from skimr::skim output.

# load packages
library(skimr)
library(dplyr)

# remove skim summary functions _I'm not interested in
skim_with(numeric = list(p0 = NULL, p25 = NULL, p75 = NULL, p100 = NULL, hist = NULL),
          integer = list(p0 = NULL, p25 = NULL, p75 = NULL, p100 = NULL, hist = NULL))

# define additional skim summary function iqr
skim_with(numeric = list(iqr = function(x) IQR(x, na.rm = TRUE)),
          integer = list(iqr = function(x) IQR(x, na.rm = TRUE)))

# compute summary statistics
my_stats <- skim(foo)
my_stats
# Skim summary statistics
#  n obs: 75 
#  n variables: 9 
# 
# Variable type: integer 
#  variable missing complete  n    mean    sd median iqr
#        id       0       75 75    2     0.82      2   2
#       s18       0       75 75 2388     0      2388   0
#         t       0       75 75  108.91 60.41     99  83
# 
# Variable type: numeric 
#  variable missing complete  n      mean      sd   median        iqr
#       op1       0       75 75   0.00041 0.0022  5e-04        0.0022
#       op2       0       75 75   3.5e-05 0.00029     0    5e-04     
#       op3       0       75 75 100       0         100        0     
#       s10       0       75 75   1.3     0           1.3      0     
#        s2       0       75 75 642.49    0.47      642.4      0.52  
#        s6       0       75 75  21.61    0.0016     21.61     0        

It's clear that 3 variables (s18, op3 and s10) have a 0 standard deviation, but 4 variables (s18, op3, s10 and s6) have 0 IQR. I can select the variables with 0 standard deviation:

constants_according_to_sd <- filter(my_stats, stat == "sd", value == 0) 

How can I select the variables with 0 IQR but nonzero standard deviation?

3 个答案:

答案 0 :(得分:1)

You can subset two times and intersect results:

# Subset with: IQR = 0
subsetA <- filter(my_stats, stat == "iqr" & value == 0)$variable
# Subset with: SD != 0
subsetB <- filter(my_stats, stat == "sd" & value != 0)$variable
# Intersect two subsets
intersect(subsetA, subsetB)
[1] "s6"

Other ways to subset data would be:

subsetA <- my_stats$variable[my_stats$stat == "iqr" & my_stats$value == 0]
subsetB <- subset(my_stats, stat == "sd" & value != 0)$variable

答案 1 :(得分:1)

You can filter your data separately and join:

filter(my_stats, stat == "sd", value > 0) %>% 
    inner_join(filter(my_stats, stat == "iqr", value == 0))

Alternately, you can pick the needed columns, spread to wide, and then filter:

library(tidyr)
my_stats %>% filter(stat %in% c("sd", "iqr")) %>% 
    select(variable, stat, value) %>%
    spread(key = stat, value = value) %>%
    filter(iqr == 0 & sd > 0)

答案 2 :(得分:1)

只需使用select_if和谓词函数。

foo %>% select_if(function(x) (IQR(x) == 0)&(sd(x) != 0))