提取任何值大于 x 的所有行
Extract all rows with any value greater than x
假设我有一个非常大的相关性 table 并且只想检查大于某个值(例如 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)}),]
您可以使用 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
到select列,其中所有值都大于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_vars
或 all
切换为 any_vars
或 any
分别为:
filter_all(any_vars(abs(.) > 0.4))
select_if(funs(any(abs(.) > 0.4)))
temp = cor(mtcars)
temp[rowSums(temp > 0.4) > 0, colSums(temp > 0.4) > 0]
在基础 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),]
我认为 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。它可能并不总是值得的。在这种特殊情况下,我认为代码非常可读,比 base 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
假设我有一个非常大的相关性 table 并且只想检查大于某个值(例如 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)}),]
您可以使用 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
到select列,其中所有值都大于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_vars
或 all
切换为 any_vars
或 any
分别为:
filter_all(any_vars(abs(.) > 0.4))
select_if(funs(any(abs(.) > 0.4)))
temp = cor(mtcars)
temp[rowSums(temp > 0.4) > 0, colSums(temp > 0.4) > 0]
在基础 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),]
我认为 tidy 方法是使用 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 的矩阵的 任何 元素。如果你只想要矩阵的行,其中该行的 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。它可能并不总是值得的。在这种特殊情况下,我认为代码非常可读,比 base 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