【问题标题】:Extract all rows with any value greater than x提取任何值大于 x 的所有行
【发布时间】:2017-11-01 15:51:27
【问题描述】:

假设我有一个非常大的相关表,并且只想检查大于某个值(例如 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)}),]

【问题讨论】:

  • @d.b 我实际上想保留“某些”值大于 0.40 的行。可以使用 any_vars() 而不是 all_vars() 来关闭。

标签: r dataframe tidyverse


【解决方案1】:

你可以使用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

注意:

如果您想要 any 值大于 0.4 的行或列,只需将 all_varsall 分别切换为 any_varsany

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

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

【讨论】:

  • 原始问题要求some值大于0.4的行;为此,您将使用any_vars
  • @dash2 我确实意识到了这一点,但我的解决方案与df[apply(df, 1, function(row) {all(abs(row) &gt; .40)}),] 的 OP 输出相匹配。所以我想他必须澄清他想要哪一个(接受我的回答暗示他想要all_vars)。无论哪种方式,将all_varsany_vars 切换是微不足道的
【解决方案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),]

【讨论】:

    【解决方案3】:
    temp = cor(mtcars)
    temp[rowSums(temp > 0.4) > 0, colSums(temp > 0.4) > 0]
    

    【讨论】:

      【解决方案4】:

      我认为tidy的方式是用gather()将相关矩阵转换成tidy格式。

      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。如果您只想要该行的 all 元素大于 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 中的所有内容通常都会更容易。因此,有时您必须将数据强制转换为不自然的格式才能(轻松)使用 tidyverse。它可能并不总是值得的。在这种特殊情况下,我认为代码可读性强,比基本 R 中的任何代码都好,但如果您的数据集很大,性能可能不是很好。

      df2 %&gt;% 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
      

      【讨论】:

        猜你喜欢
        • 2019-07-13
        • 2022-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-05
        • 1970-01-01
        • 2021-09-18
        相关资源
        最近更新 更多