将基于多个参数的子集转换为循环函数

Turning a subset based on multiple parameters into a looping function

我有一个包含 3000 多个项目的数据框(每一行都是一个新项目,第一列中有 item_id),每个后续列中有 2500 多个属性。

item_id    attribute_1    attribute_2 ... category_1 ... category_2
x3902      1              5               1              0
x1402      2              0               1              1

我能够成功抓取满足给定属性和类别的 10 个项目的随机列表:

subset_of_items = sample(subset(df$item_id, (df$attribute1 == 3 & df$category_2 == 1 )),10)

我需要对 30 多个属性 + 类别的组合重复此操作。所以我希望创建一个循环并将输出保存到 table 中的函数,其中每个 table 列都是满足一组条件的 10 个项目的列表。

这是我所能得到的,但无法成功运行:

df <- read.csv ("data.csv",sep=",")

attribute <- c("attribute_1", "attribute_2", "attribute_3")
value <- c(1, 2, 5)
category <- c("category_1", "category_1", "category_2")

function1 <- function(x, attribute_x, value_x, category_x)
{
  dftemp = subset(x[["item_id"]], (x[[attribute_x]] == value_x & x[[category_x]] == 1 ))
  output <- cbind(output, dftemp)
}

function1(df, attribute, value, category)

锦上添花的是将每一列命名为 attribute_x

您可以执行以下操作(这使用 data.table 方法)

  1. 将你的 df 设置为 data.table
library(data.table)
df <- read.csv("data.csv",sep=",")
setDT(df)
  1. 修改函数,调用get_subset(),return是满足属性和类别要求的item_ids向量,使用get()。它 还检查您是否有 size 个项目 return,并用 as.character(NA) 填充以确保 returned 向量的长度 = size
get_subset <- function(x, attribute_x, value_x, category_x, size=10)
{
  subset = x[get(attribute_x)==value_x & get(category_x) == 1, .(item_id)] %>% 
    .[sample(1:.N, size=min(size, .N)), item_id]
  if(length(subset)<size) subset=c(subset,rep(as.character(NA),size-length(subset)))
  return(subset)
}
  1. 将您感兴趣的组合放入一个小的data.table
combinations = data.table(
  attribute = c("attribute_1", "attribute_2"),
  value = c(1, 5),
  category = c("category_1", "category_2")
)
  1. 使用lapply循环组合的行,每次将组合的属性、值和类别值提供给get_subset函数
result = lapply(seq(1,nrow(combinations)), function(i) {
    items = data.table(get_subset(
      x=df,
      attribute_x = combinations[i,attribute],
      value_x = combinations[i,value],
      category_x = combinations[i, category],
      size=10))
    setNames(items, combinations[i,attribute])
})

return 是一个包含单列的 data.table 列表,以该贡献的属性命名

  1. 使用 do.call 和 cbind 将它们绑定到一个 data.table
result = do.call(cbind, result)

如果这是你的原创df

df = data.table(
  item_id = paste0("x", stringr::str_pad(sample(1:1000,100),width = 4,side = "left",pad = "0")),
  attribute_1=sample(1:10, 100, replace=T),
  attribute_2=sample(1:10, 100, replace=T),
  category_1=sample(c(0,1),100, replace=T),
  category_2=sample(c(0,1),100, replace=T)
)

然后上面的 combinations,将 return 类似于 result 中的以下内容(请注意,我的 df 示例使用没有种子的样本,因此您的结果会有所不同)

    attribute_1 attribute_2
 1:       x7511       x7302
 2:       x0325       x0956
 3:       x6748       x1893
 4:       x4462       x6958
 5:       x4146        <NA>
 6:       x5407        <NA>
 7:        <NA>        <NA>
 8:        <NA>        <NA>
 9:        <NA>        <NA>
10:        <NA>        <NA>