在R中组合for循环和ifelse

fdbelqdn  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(158)

我正在尝试编写一个for循环,它将为固定列生成相关性(LPS0)与数据集中所有其他列的相关性。我不想使用相关性矩阵,因为我只关心LPS0与所有其他列的相关性,而不是其他列与它们自身的相关性。然后我想包含一个if语句,以便只打印显著相关性(p. value〈= 0.05)。我遇到了一些问题,其中一些p. value返回为NA,所以我切换到if_else循环。然而,我现在得到了一个错误。我的代码如下:

for(i in 3:ncol(microbiota_lps_0_morm)) { 
  morm_0 <- cor.test(microbiota_lps_0_morm$LPS0, microbiota_lps_0_morm[[colnames(microbiota_lps_0_morm)[i]]], method = "spearman")
  if_else(morm_0$p.value <= 0.05, print(morm_0), print("Not Sig"), print("NA"))
}

返回第一个值,然后循环停止并出现以下错误:
if_else()中的错误:! true的长度必须为1(condition的长度),而不是8。回溯:1. dplyr::if_else(morm_0$p.value〈= 0.05,打印(morm_0),打印("非签名"),打印("不适用"))
怎样才能使循环打印仅在p值〈-0.05时发生?

vd2z7a6w

vd2z7a6w1#

这里有一段很长的代码,它可以完成整个事情,它可能有点过头了,但是你可以只使用矩阵,然后使用你需要的任何东西,它利用了tidyverse。

df <- select_if(mtcars,is.numeric)
glimpse(df)
# keeping real names
dict <- cbind(original=names(df),new=paste0("v",1:ncol(df)))
# but changing names for better data viz
colnames(df) <- paste0("v",1:ncol(df))

# correlating between variables + p values
pvals <- list()
corss <- list()
for (coln in colnames(df)) {
  pvals[[coln]] <- map(df, ~ cor.test(df[,coln], .)$p.value)
  corss[[coln]] <- map(df, ~ cor(df[,coln], .))
}

# Keeping both matrices in a list
matrices <- list(
  pvalues = matrix(data=unlist(pvals),
                     ncol=length(names(pvals)),
                     nrow=length(names(pvals))),
  
  correlations = matrix(data=unlist(corss),
                   ncol=length(names(corss)),
                   nrow=length(names(corss)))
)

rownames(matrices[[1]]) <- colnames(df)
rownames(matrices[[2]]) <- colnames(df)

# Creating a combined data frame
long_cors <- expand.grid(Var1=names(df),Var2=names(df)) %>% 
  mutate(cor=unlist(matrices["correlations"]),
         pval=unlist(matrices["pvalues"]),
         same=Var1==Var2,
         significant=pval<0.05,
         dpcate=duplicated(cor)) %>% 
  # Leaving no duplicants, non-significant or self-correlation results
  filter(same ==F,significant==T,dpcate==F) %>%
  select(-c(same,dpcate,significant))

# Plotting correlations
long_cors %>%mutate(negative=cor<0) %>% 
  ggplot(aes(x=Var1,y=Var2,
             color=negative,size=abs(cor),fill=Var2,
             label=round(cor,2)))+
  geom_label(show.legend = F,alpha=0.2)+
  scale_color_manual(values = c("black","darkred"))+
  # Sizing each correlation by it's magnitude
  scale_size_area(seq(1,100,length=length(unique(long_cors$Var1))))+ theme_light()+
  theme(axis.text = element_text(face = "bold",size=12))+
  labs(title="Correlation between variables",
       caption = "p < 0.05")+xlab("")+ylab("")
oxosxuxt

oxosxuxt2#

如果要将矩阵的一列与其余列关联起来,只需调用一个函数即可:

mtx <- matrix(rnorm(800), ncol=8)
cor(mtx[,1], mtx[,-1])

但是,您将无法获得p值。要获得p值,我建议使用以下方法:

library(tidyverse)
significant <- map_dbl(2:ncol(mtx), 
      ~ cor.test(mtx[,1], mtx[,.], use="p", method="s")$p.value)

每当你觉得需要在R中使用for循环时,很可能你应该使用另一种方法。for是一种非常非R的构造,而R给出了很多更好的方法来处理同样的问题。tidyverse的map_*函数家族只是其中之一。在基本R中,另一种方法是使用apply

significant <- apply(mtx[,-1], 2, 
         \(x) cor.test(x, mtx[,1], method="s", use="p")$p.value)

相关问题