【问题标题】:Nested dplyr Loop in rr中的嵌套dplyr循环
【发布时间】:2020-10-06 18:03:02
【问题描述】:

我试图在 r 中做一个嵌套循环来做一些复杂的随机抽样。简要介绍一下我所拥有的以及我正在努力完成的工作。

我有一个包含 3 个变量的数据集(下面的示例代码)。每个变量都是 1 或 0。我想为每个变量采样不同的次数,但只针对“1”值。

例如,对于“A”列,我想随机抽取 1 个在该列中具有“1”值的唯一行。

我是循环新手,嵌套循环让我卡住了。

编辑:修复示例数据框。

library(tidyverse)

###create sample data set

id<-c('l','m','n','o','p')

A<-c(0,1,1,1,1)

B<-c(1,1,1,0,1)

C<-c(1,1,1,0,1)

RISK_LEVEL<-c('3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated')

data<-as.data.frame(id, A, B, C, RISK_LEVEL)


#list with number of samples I want to take from each column
high_count<-c(1,3,2)

#list of columns I want to sample from
groups<-c('A','B','C')

#create blank dataframe to house output
high_samp<-list(matrix(,nrow=5,ncol=5))

###nested loop
for (j in 1:length(groups)) {

  for (i in 1:length(high_count)) {

high_samp[[i]]<-data %>%

  filter(RISK_LEVEL=='3 - Elevated') %>%

  filter([[j]]==1) %>%

  sample_n(high_count[[i]])

}
}

#turns list of dataframes into one dataframe
high_samp<-bind_rows(high_samp)

dplyr 似乎不喜欢下面的 sn-p,因为它不接受 filter 函数的下标。

filter([[j]]==1)

【问题讨论】:

  • 你能分享一下预期的结果吗?您是否在寻找要退回的 ID?
  • 我的最终预期结果是要返回的所有列(包括 ID + 我在实际集合中拥有的其他列),并且有一个与每列所需的 n 计数匹配的行样本(high_count 是列表在示例中指定了这一点)。本质上,我正在尝试对每个层进行不同计数的分层随机抽样。
  • 如果过滤列 A、B、C 只包含 1,为什么要采样?
  • 我的用例是一个有监督的机器学习训练集,每个组都有特定数量的示例。整个数据集约为 50k 行,但我只需要 1500 cmets 给评估者。在实际数据集中,大多数行只有 1-3 列中的“1”。

标签: r loops dplyr nested tidyverse


【解决方案1】:

我创建了一个规范数据框spec,它结合了groupshigh_count。 有了这个,我可以使用lapply 和 curly curl 运算符制定解决方案。首先,我计算出 sample_size 并将其用于sample_n 函数调用。

library(dplyr)

###create sample data set
id <- c('l','m','n','o','p')
A <- c(0,1,1,1,1)
B <- c(1,1,1,0,1)
C <- c(1,1,1,0,1)
RISK_LEVEL <- c('3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated')
data <- data.frame(id, A, B, C, RISK_LEVEL)

high_count<-c(1,3,2)
groups<-c('A','B','C')
spec <- data.frame(groups = groups, high_count = high_count, stringsAsFactors = FALSE)

result_list <- lapply(spec$groups, function(x) { 
  sample_size <- spec %>%
    filter(groups == {{x}}) %>%
    .$high_count
  result <- data %>% 
    filter(get(x) == 1) %>%
    sample_n(sample_size)
})

结果:

> result_list
[[1]]
  id A B C   RISK_LEVEL
1  p 1 1 1 3 - Elevated

[[2]]
  id A B C   RISK_LEVEL
1  m 1 1 1 3 - Elevated
2  p 1 1 1 3 - Elevated
3  l 0 1 1 3 - Elevated

[[3]]
  id A B C   RISK_LEVEL
1  m 1 1 1 3 - Elevated
2  l 0 1 1 3 - Elevated

可以结合:

result <- bind_rows(result_list)

【讨论】:

  • 这很好用,谢谢。我将阅读有关 function(x) 的内容,以便将来使用它。
  • 我想我大部分都遵循这一点,除了一行。 .$high_count 发生了什么?
  • %&gt;% .$highcount 选择值;否则传递一个数据帧。我相信还有其他有用的方法。
  • 好的,这很有道理。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 2016-05-28
  • 2014-03-25
  • 2023-03-02
  • 1970-01-01
相关资源
最近更新 更多