【问题标题】:Looping in Dplyr在 Dplyr 中循环
【发布时间】:2018-04-17 18:45:48
【问题描述】:

我的问题是指在 Dplyr 中循环。我正在尝试确定自变量(IV1:IV5)的每个独特组合的 DV1 的平均值、计数和方差。我的数据如下所示:

DV1     IV1     IV2     IV3     IV4  IV5
506.2   Male    Canada  alpha   low  Orange
418.7   Female  Canada  beta    mid  Orange
380.3   Male    Canada  alpha   high Red
347.3   Male    Canada  alpha   mid  Red
241.6   Female  UStates alpha   mid  Blue
223.7   Female  Canada  beta    low  Green
220.9   Male    Canada  alpha   low  Orange
201.1   Male    Canada  alpha   low  Red
193.8   Female  Canada  beta    mid  Green
179.7   Female  UStates beta    low  Orange
170.7   Male    UStates beta    mid  Blue
149.5   Male    UStates beta    low  Green
146.2   Male    Canada  beta    high Green
144.2   Female  UStates beta    mid  Red
141.5   Male    Canada  beta    high Blue
138.6   Male    Canada  beta    mid  Blue
137     Male    Canada  beta    low  Red
136     Female  UStates beta    mid  Orange
135.9   Female  UStates beta    low  Red
134.6   Male    UStates alpha   mid  Orange
129     Female  UStates beta    mid  Green
127.1   Female  UStates beta    low  Green
120.4   Male    UStates beta    low  Blue
119.3   Female  UStates beta    high Red
118.6   Female  Canada  alpha   low  Blue
116.2   Female  Canada  alpha   high Green
113.7   Male    UStates beta    high Green
112.9   Female  UStates beta    low  Green
112.6   Male    Canada  alpha   mid  Green
112.2   Male    Canada  alpha   mid  Orange
109     Female  Canada  beta    high Orange
108.1   Female  Canada  alpha   mid  Blue
99.1    Female  Canada  alpha   high Blue
95.6    Male    UStates beta    mid  Green
88.1    Male    Canada  alpha   high Blue
83.9    Female  Canada  beta    high Green
83.7    Male    Canada  alpha   low  Green
80.8    Male    Canada  alpha   high Orange
79.9    Female  UStates alpha   high Blue
78      Female  UStates alpha   mid  Red
76.3    Female  UStates alpha   low  Blue
74.1    Female  UStates beta    high Orange
65.7    Female  UStates beta    high Red
62.1    Male    UStates alpha   high Red
54.8    Male    Canada  beta    low  Blue
54      Male    UStates alpha   mid  Red
42.8    Female  UStates alpha   low  Red
39.6    Male    UStates alpha   high Orange
19.5    Male    UStates alpha   low  Orange
19.2    Female  Canada  alpha   mid  Green

使用 Dplyr,我已经能够创建它。我需要 IV1:IV5 的每个独特组合的描述性统计信息下可用的信息

mod1=data1 %>%                                           
  group_by(IV1)%>%  
  summarise(avg_banding=mean(DV1),             
            total.count=n(),                          
            variance=var(DV1)) %>%                 
  print(n=50)     
#Descriptive statistics for the entire group (required!)
sum(mod1$avg_banding) 
mean(mod1$avg_banding)
mean(mod1$total.count)
mod1_2=mod1[complete.cases(mod1),] 
sum(mod1_2$variance) 

正如您可能知道的那样,我必须对每一种可能的组合都这样做...... (IV1) (IV1,IV2) (IV1,IV2,IV3) (IV2, IV3) 等等。有很多组合,我想知道是否有更简单的方法来做到这一点,而不是为每一个都插上!我尝试使用 for 循环但没有成功。

mod2=data1 %>%                                             
  group_by(IV2)%>%  
  summarise(avg_banding=mean(DV1),             
            total.count=n(),                          
            variance=var(DV1)) %>%                 
  print(n=50)     

sum(mod2$avg_banding) 
mean(mod2$avg_banding)
mean(mod2$total.count)
mod2_2=mod2[complete.cases(mod2),] 
sum(mod2_2$variance)

非常感谢任何帮助!谢谢!

【问题讨论】:

  • 这样的事情可能会给你一个起点stackoverflow.com/questions/18298825/…
  • 谢谢朋友。在发布我的问题之前,我看到了该线程。问题在于,combn 仅以 2 的组合发布列。我需要一个包含所有可能组合的答案。例如,IV1、IV1+IV2、IV2+IV3+IV4+IV5、IV3+IV4+IV5 等(还有数百种)!我绝对可以使用 combn(names(data), 1,simplify=FALSE),然后是 combn(names(data, 2, simple = FALSE) 等,直到我从 1:5 开始,但我希望有一个更简单的方式。

标签: r for-loop dplyr combn


【解决方案1】:

您可以使用dplyrtidyr 执行此操作。通过使用crossingleft_join 和原始数据,然后使用group_bysummarize,您可以获得输入数据帧的每个组合。我的样本限制为 10 行。请记住下次包含一个可重现的示例,该示例包含使用dput 轻松输入到 R 中的数据。

library(dplyr)
library(tidyr) #For expand

data <- tibble::tribble(~DV1, ~IV1, ~IV2, ~IV3, ~IV4, ~IV5,
   506.2,   "Male",   "Canada",  "alpha",   "low", "Orange",
   418.7,   "Female", "Canada",  "beta",    "mid",  "Orange",
   380.3,   "Male",   "Canada",  "alpha",   "high", "Red",
   347.3,   "Male",   "Canada",  "alpha",   "mid",  "Red",
   241.6,   "Female", "UStates", "alpha",   "mid",  "Blue",
   223.7,   "Female", "Canada",  "beta",    "low",  "Green",
   220.9,   "Male",   "Canada",  "alpha",   "low",  "Orange",
   201.1,   "Male",   "Canada",  "alpha",   "low",  "Red",
   193.8,   "Female", "Canada",  "beta",    "mid",  "Green",
   179.7,   "Female", "UStates", "beta",    "low",  "Orange"
  )

expand(data, IV1,IV2, IV3, IV4, IV5) %>% 
  left_join(data) %>% 
  group_by(IV1, IV2, IV3, IV4, IV5) %>% 
  summarize(mean = mean(DV1, na.rm = TRUE),
            var = var(DV1, na.rm = TRUE),
            n = n())

【讨论】:

  • 谢谢!非常感谢!
【解决方案2】:

一种方法可能是创建一个记录不同模式的变量。我将每一列重新编码为二进制 0,1 格式,然后将它们连接起来。生成的变量 pattern 是每个组合的唯一“代码”。

df$male<-ifelse(df$IV1=="Male",1,0)
df$ustates<-ifelse(df$IV2=="UStates",1,0)
df$alpha<-ifelse(df$IV3=="alpha",1,0)
df$low<-ifelse(df$IV4=="low",1,0)
df$red<-ifelse(df$IV5=="red",1,0)


attach(df)
df$pattern<-paste(male,ustates,alpha,low,red) #concatenate into a "code"
library(psych)
describe.by(df$DV1,df$pattern)

【讨论】:

  • 为什么在连接之前需要转换成数字?
  • 嗨@BenBolker --> 我明白你的意思,尽管这个想法来自早期的分析,我还想要计算每一行,所以重新编码为 0,1 是必要的。但你是对的,“代码”可能只是串联的字符串。
【解决方案3】:

这个怎么样:

library(HapEstXXR)
library(dplyr)

# Import the data
data1 = data.frame(DV1 = c(506.2,418.7,380.3,347.3,241.6,223.7,220.9,201.1,193.8,179.7,170.7,149.5,146.2,144.2,141.5,138.6,137,136,135.9)
                   , IV1 = c("Male","Female","Male","Male","Female","Female","Male","Male","Female","Female","Male","Male","Male","Female","Male","Male","Male","Female","Female")
                   , IV2 = c("Canada","Canada","Canada","Canada","UStates","Canada","Canada","Canada","Canada","UStates","UStates","UStates","Canada","UStates","Canada","Canada","Canada","UStates","UStates")
                   , IV3 = c("alpha","beta","alpha","alpha","alpha","beta","alpha","alpha","beta","beta","beta","beta","beta","beta","beta","beta","beta","beta","beta")
                   , IV4 = c("low","mid","high","mid","mid","low","low","low","mid","low","mid","low","high","mid","high","mid","low","mid","low")
                   , IV5 = c("Orange","Orange","Red","Red","Blue","Green","Orange","Red","Green","Orange","Blue","Green","Green","Red","Blue","Blue","Red","Orange","Red")
)

# Create a powerset of IV1, IV2, IV3, IV4, IV5
cols = c("IV1", "IV2", "IV3", "IV4", "IV5")
cols_combos = powerset(cols)

# Create an empty data frame to store the statistics in for each column combination
stats_df = data.frame()

# Function to calculate stats for a particular column combination
getStats = function(data1, stats_df, cols) {
  mod = data1 %>%
    group_by_(.dots = cols) %>%
    summarise(avg_banding=mean(DV1),
              total.count=n(),
              variance=var(DV1)) %>%
    mutate(COMBO = paste0(cols, collapse=",")) %>%
    group_by(COMBO) %>%
    summarise(sum_avg = sum(avg_banding)
              , avg_avg = mean(avg_banding)
              , avg_cnt = mean(total.count)) %>%
    ungroup() %>%
    select(COMBO, sum_avg, avg_avg, avg_cnt)

  stats_df = rbind(stats_df, mod)
  return(stats_df)
}

# Loop through column combinations to generate stats for each
for(col in cols_combos) {
  stats_df = getStats(data1, stats_df, col)
}

需要包 HapEstXXR 以创建所有列组合的 powerset。结果存储在名为 stats_df 的数据框中。

【讨论】:

  • 嗨,朋友。非常感谢你的帮助!该脚本效果很好。只是一个额外的问题。最后,我得到一个带有#A tibble 的缩短表:[number here] x 4。该表有 10 种 IV1:IV5 组合,并且在表的末尾是“... with [number here]更多行。COMBO 提供了 10 种组合(IV1、IV2、IV1+IV2、IV3 等)。我将如何获得其余的?我试过这个 for(col in cols_combos) { stats_df = getStats(data1 , stats_df, col) 打印(stats_df) }
  • 使用以下命令:View(stats_df)(V 的大写很重要)。如果您还没有,我建议您下载并使用 RStudio IDE。它使查看数据帧变得容易。
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多