【问题标题】:Split a data frame in R and apply function to each part在 R 中拆分数据框并将函数应用于每个部分
【发布时间】:2020-10-03 13:01:20
【问题描述】:

我有一个包含 5 列和数千行的大数据框。数据框“d”如下所示:

Material  Input_Wt  Price
   1        10       13
   3         6       18
   1         9       12
   2        12       15
   3         4        8
   1        14       10

我需要对数据进行回归,以预测每种材料在不同输入权重下的价格。要应用的回归技术取决于唯一材料编号的记录数。所以我需要处理与唯一材料编号有关的所有记录。一起。

所以我根据物料号拆分数据。放入多个 csv 文件并使用代码将它们保存在工作目录中:

SPLIT.DATA <- split(d, d$Material, drop = FALSE)

lapply(names(SPLIT.DATA), function(nm)
write.csv(SPLIT.DATA[[nm]], paste0(nm, ".csv"), row.names = FALSE, quote = FALSE))

文件看起来像:

Material  Input_Wt  Price
   1         10       13
   1          9       12
   1         14       10

Material  Input_Wt  Price
   2         12       15 

Material  Input_Wt  Price
   3         6        18
   3         4         8

然后我将所有这些文件调用到列表中的 R 中:

fileNames <- Sys.glob("*.csv")

并分别对它们中的每一个应用函数并将附加的输出保存在单个文件中:

for (fileName in fileNames){
  inp = read.csv(fileName,header = TRUE,sep = ",")
  if (nrow(inp)==3){
    print(RandomForest())
  }else if (nrow(inp)==2){
    print(KNN())
  }else if (nrow(inp)==1){
    print("Insufficient Data")
  }
}

'KNN' 和 'RandomForest' 是我定义的独立函数。

我最终得到了想要的输出:

Material  Input_Wt  Price Predicted_Price
   1         10       13       14.5
   1          9       12       13.8
   1         14       10        9.2
   2         12       15       16.1
   3         6        18       17.5
   3         4         8        9.7

这里的问题是这种方式效率不高。我首先必须将数据帧拆分并写入多个 csv 文件,然后将它们一个一个调用到 R 上以再次处理它们。

有没有一种方法可以直接完成整个过程,而无需将数据帧写入 csv 文件并再次调用它们?

【问题讨论】:

  • 您不必写入文件并重新读取。将它们拆分为单独的数据框后,为什么不直接使用这些数据框?

标签: r loops dataframe apply


【解决方案1】:

您的标题是bytapply 的面向对象的包装器)的基本定义,与split 不同,它维护一个函数参数。考虑定义一个接收数据帧作为参数的函数,并使用by 调用它。

my_func <- function(inp){
  if (nrow(inp)==3){
    obj <- RandomForest()
  }else if (nrow(inp)==2){
    obj <- KNN()
  }else if (nrow(inp)==1){
    obj <- "Insufficient Data"
  }
  print(obj)

  return(obj)
}

obj_list <- by(df, df$Material, my_func)

【讨论】:

    【解决方案2】:

    不要拆分您的数据框,只需使用子集语句:

    df[df$Material == 1,]
    subset(df, df$Material == 1)
    

    或与包裹dplyr:

    df %>%
      filter(Material == 1)
    

    如果您想根据每个组的条目数应用函数,请尝试类似

    df %>%
      group_by(Material) %>%
      mutate(Predicated_Price=case_when(n() == 3 ~ "RandomForest()",
                                        n() == 2 ~ "KNN()",
                                        n() == 1 ~ "Insufficient Data"))
    

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多