删除 dplyr::group_by 之后和 prcomp 之前的等方差列
Remove columns of equal variance after dplyr::group_by and before prcomp
我正在使用 dplyr
对大型数据集中的多个组执行 pca。当使用 group_by
函数对数据进行分组时,一些变量具有相等的方差,因此 pca 不能 运行。我怎样才能删除任何等方差的列,然后对剩下的执行prcomp
?下面的虚拟数据。谢谢。
为 setosa 添加等方差 - Sepal.Length。
library(dplyr)
iris[1:50,1]<-0
尝试 运行 方差相等的 pcas
> iris%>%
+ group_by(Species)%>%
+ group_map(~prcomp(.[,1:4], scale.=T))
Error in prcomp.default(.[, 1:4], scale. = T) :
cannot rescale a constant/zero column to unit variance
检查方差是否相等
> iris%>%
+ group_by(Species)%>%
+ group_map(~names(.[,1:4][, sapply(.[,1:4], function(v) var(v, na.rm=TRUE)==0)]))
[[1]]
[1] "Sepal.Length"
[[2]]
character(0)
[[3]]
character(0)
尝试排除等方差列和 运行 pcas
> iris%>%
+ group_by(Species)%>%
+ group_map(~sapply(.[,1:4], function(v) var(v, na.rm=TRUE)>0))%>%
+ group_map(~prcomp(.[,1:4], scale.=T))
Error in UseMethod("group_split") :
no applicable method for 'group_split' applied to an object of class "list"
我们可以使用 map_if
检查条件然后应用函数。
library(tidyverse)
iris %>%
group_split(Species, keep = FALSE) %>%
map_if(~all(map_dbl(.x, var) != 0), ~prcomp(.x, scale. = TRUE),
.else = function(x) return(NULL))
#[[1]]
#NULL
#[[2]]
#Standard deviations (1, .., p=4):
#[1] 1.7106550 0.7391040 0.6284883 0.3638504
#Rotation (n x k) = (4 x 4):
# PC1 PC2 PC3 PC4
#Sepal.Length -0.4823284 -0.6107980 0.4906296 0.3918772
#Sepal.Width -0.4648460 0.6727830 0.5399025 -0.1994658
#Petal.Length -0.5345136 -0.3068495 -0.3402185 -0.7102042
#Petal.Width -0.5153375 0.2830765 -0.5933290 0.5497778
#[[3]]
#Standard deviations (1, .., p=4):
#[1] 1.5667601 0.9821979 0.6725116 0.3581596
#Rotation (n x k) = (4 x 4):
# PC1 PC2 PC3 PC4
#Sepal.Length 0.5544765 -0.4324382 0.01239569 0.71091442
#Sepal.Width 0.4755317 0.4401787 0.75272551 -0.11626101
#Petal.Length 0.5501112 -0.4296642 -0.20236407 -0.68688796
#Petal.Width 0.4047258 0.6592637 -0.62633812 0.09627561
如果我们只想删除方差为 0 的列而不是整个组,我们可以使用 select_if
到 select 列
iris %>%
group_split(Species, keep = FALSE) %>%
map(~.x %>% select_if(~var(.) != 0) %>% prcomp(scale. = TRUE))
我正在使用 dplyr
对大型数据集中的多个组执行 pca。当使用 group_by
函数对数据进行分组时,一些变量具有相等的方差,因此 pca 不能 运行。我怎样才能删除任何等方差的列,然后对剩下的执行prcomp
?下面的虚拟数据。谢谢。
为 setosa 添加等方差 - Sepal.Length。
library(dplyr)
iris[1:50,1]<-0
尝试 运行 方差相等的 pcas
> iris%>%
+ group_by(Species)%>%
+ group_map(~prcomp(.[,1:4], scale.=T))
Error in prcomp.default(.[, 1:4], scale. = T) :
cannot rescale a constant/zero column to unit variance
检查方差是否相等
> iris%>%
+ group_by(Species)%>%
+ group_map(~names(.[,1:4][, sapply(.[,1:4], function(v) var(v, na.rm=TRUE)==0)]))
[[1]]
[1] "Sepal.Length"
[[2]]
character(0)
[[3]]
character(0)
尝试排除等方差列和 运行 pcas
> iris%>%
+ group_by(Species)%>%
+ group_map(~sapply(.[,1:4], function(v) var(v, na.rm=TRUE)>0))%>%
+ group_map(~prcomp(.[,1:4], scale.=T))
Error in UseMethod("group_split") :
no applicable method for 'group_split' applied to an object of class "list"
我们可以使用 map_if
检查条件然后应用函数。
library(tidyverse)
iris %>%
group_split(Species, keep = FALSE) %>%
map_if(~all(map_dbl(.x, var) != 0), ~prcomp(.x, scale. = TRUE),
.else = function(x) return(NULL))
#[[1]]
#NULL
#[[2]]
#Standard deviations (1, .., p=4):
#[1] 1.7106550 0.7391040 0.6284883 0.3638504
#Rotation (n x k) = (4 x 4):
# PC1 PC2 PC3 PC4
#Sepal.Length -0.4823284 -0.6107980 0.4906296 0.3918772
#Sepal.Width -0.4648460 0.6727830 0.5399025 -0.1994658
#Petal.Length -0.5345136 -0.3068495 -0.3402185 -0.7102042
#Petal.Width -0.5153375 0.2830765 -0.5933290 0.5497778
#[[3]]
#Standard deviations (1, .., p=4):
#[1] 1.5667601 0.9821979 0.6725116 0.3581596
#Rotation (n x k) = (4 x 4):
# PC1 PC2 PC3 PC4
#Sepal.Length 0.5544765 -0.4324382 0.01239569 0.71091442
#Sepal.Width 0.4755317 0.4401787 0.75272551 -0.11626101
#Petal.Length 0.5501112 -0.4296642 -0.20236407 -0.68688796
#Petal.Width 0.4047258 0.6592637 -0.62633812 0.09627561
如果我们只想删除方差为 0 的列而不是整个组,我们可以使用 select_if
到 select 列
iris %>%
group_split(Species, keep = FALSE) %>%
map(~.x %>% select_if(~var(.) != 0) %>% prcomp(scale. = TRUE))