使用大于x的任何值提取所有行

时间:2017-11-01 15:51:28

标签: r dataframe tidyverse

假设我有一个非常大的相关表,并且只想检查大于某个值(例如,0.40)的相关性。如何提取值大于0.40的所有行或列?

我可以使用apply执行此操作,但希望在tidyverse中执行操作。

library(tidyverse)

df <- mtcars %>% 
  select_if(is.numeric) %>% 
  cor() %>% 
  round(digits = 2) %>% 
  as.data.frame() 

df[apply(df, 1, function(row) {all(abs(row) > .40)}),]

4 个答案:

答案 0 :(得分:5)

您可以使用filter_all

library(tidyverse)

df <- mtcars %>% 
  select_if(is.numeric) %>% 
  cor() %>% 
  round(digits = 2) %>% 
  as.data.frame() %>%
  filter_all(all_vars(abs(.) > 0.4))

<强>结果:

    mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
1  1.00 -0.85 -0.85 -0.78  0.68 -0.87  0.42  0.66  0.60  0.48 -0.55
2 -0.85  1.00  0.90  0.83 -0.70  0.78 -0.59 -0.81 -0.52 -0.49  0.53

要选择所有值均大于0.4的,请使用select_if

df <- mtcars %>% 
  select_if(is.numeric) %>% 
  cor() %>% 
  round(digits = 2) %>% 
  as.data.frame() %>%
  select_if(funs(all(abs(.) > 0.4)))

<强>结果:

       mpg   cyl
mpg   1.00 -0.85
cyl  -0.85  1.00
disp -0.85  0.90
hp   -0.78  0.83
drat  0.68 -0.70
wt   -0.87  0.78
qsec  0.42 -0.59
vs    0.66 -0.81
am    0.60 -0.52
gear  0.48 -0.49
carb -0.55  0.53

注意:

如果您想要任何值大于0.4的行或列,只需分别与all_varsall切换any_varsany

filter_all(any_vars(abs(.) > 0.4))

select_if(funs(any(abs(.) > 0.4)))

答案 1 :(得分:2)

在基础R中,您可以像这样使用rowSums

# get correlation matrix, values rounded to second digit
dat <- round(cor(mtcars[sapply(mtcars, is.numeric)]), 2)

# subset rows
dat[rowSums(abs(dat) > 0.4) == ncol(dat),]

答案 2 :(得分:1)

temp = cor(mtcars)
temp[rowSums(temp > 0.4) > 0, colSums(temp > 0.4) > 0]

答案 3 :(得分:1)

我认为整洁方式是将关联矩阵转换为整齐格式gather()

df1 <- mtcars %>% 
    select_if(is.numeric) %>% 
    cor() %>% 
    round(digits = 2) %>% 
    as.data.frame() %>%
    rownames_to_column %>%
    gather(colname, value, -rowname) %>%
    filter(abs(value) >= 0.4) 

请注意,这假设您需要矩阵的任何元素,其中相关性大于0.4。如果你只想要那行所有元素的矩阵行而不是0.4,我想你可以做到

df2 <- mtcars %>% 
    select_if(is.numeric) %>% 
    cor() %>% 
    round(digits = 2) %>% 
    as.data.frame() %>%
    rownames_to_column %>%
    gather(colname, value, -rowname) %>%
    group_by(rowname) %>%
    filter(min(abs(value)) >= 0.4) 

结果仍然是长(即整洁)格式。将自然是矩阵(例如相关矩阵)的数据转换为长格式是否合适是有争议的,但如果您的数据是整齐的格式,那么整数中的所有内容都更容易理解。因此,有时您必须强制将数据转换为不自然的格式以便(轻松)使用tidyverse。它可能并不总是值得的。在这种特殊情况下,我认为代码是可读的,比基础R中的任何东西都要多,但如果你的数据集很大,性能可能不是很好。

df2 %>% spread(colname, value)的结果是

  rowname am    carb  cyl   disp  drat  gear  hp    mpg   qsec  vs    wt   
1 cyl     -0.52  0.53  1.00  0.90 -0.70 -0.49  0.83 -0.85 -0.59 -0.81  0.78
2 mpg      0.60 -0.55 -0.85 -0.85  0.68  0.48 -0.78  1.00  0.42  0.66 -0.87