【问题标题】:Subsetting a data frame on multiple vectors/lists and applying a function for each subset combination in R [duplicate]在多个向量/列表上对数据框进行子集化,并为 R 中的每个子集组合应用一个函数 [重复]
【发布时间】:2018-02-25 06:07:42
【问题描述】:

我有一个数据框 (df),其中包含多个列,例如项目、公司、地区、日期、价格。我想应用一些函数或转换,例如使用下面 3 个向量的组合/分组将价格的平均值添加到每个子集的价格列,以便在应用函数之前对我的数据框进行子集化。这三个向量包含数据框中不同的项目、公司和区域,并且也有不同的长度,即比公司或区域有更多不同的项目。

数据框示例:

Date | Region | Company | Item | Price
---------------------------------------
7/16 | NW     | ABC     | Phone| 200
8/16 | NW     | ABC     | Phone| 200
8/16 | SW     | DEF     | Food | 100
8/16 | SW     | DEF     | Food | 50
9/16 | NW     | ABC     | Tools| 100
9/16 | NW     | DEF     | Tools| 50

以下 3 个向量:

item <- unique(df$item) # 3 different items
company <- unique(df$company) # 2 different companies
region <- unique(df$region) # 2 regions

我正在考虑运行一个嵌套的 for 循环并在循环中应用一个函数。这似乎真的很低效,最重要的是我不确定我是否做得正确。

我想象的 for 循环会是这样的......

for (i in seq_along(item))
{
  for (j in seq_along(company))
  {
    for (k in seq_along(region))
    {
      x <- df[df$item==i & df$company==j & df$region==k,]
      x$Price <- x$Price + mean(x$Price)
      return(x)
    }
  }
}

我正在寻找的输出是这样的,因为每个分组并将该组的平均价格添加到 df 的价格列中:

Date | Region | Company | Item | Price
---------------------------------------
7/16 | NW     | ABC     | Phone| 400
8/16 | NW     | ABC     | Phone| 400
8/16 | SW     | DEF     | Food | 175
8/16 | SW     | DEF     | Food | 125
9/16 | NW     | ABC     | Tools| 200
9/16 | NW     | DEF     | Tools| 100

有没有更好的方法来做到这一点?更好的 for 循环还是一些 sapply 或 lapply 方法?我不确定如何处理这个问题,因为 3 个向量的长度不同。

【问题讨论】:

  • 它太宽泛了。请提供您的数据框和函数的可重现示例。
  • by(df, list(df$item, df$company, df$region), somefunc) 或者dplyr:;group_by(df, item, company, region) %&gt;% ... 的tidyverse。
  • 添加了我想要应用的示例数据框和函数以及所需的输出!
  • for 循环在 R 中很容易避免:我建议您了解 dplyr 及其 group_by 功能。
  • 我刚刚标记的副本是关于sum而不是mean,但逻辑是一样的。

标签: r for-loop dplyr lapply sapply


【解决方案1】:

group_bymutate 可以解决问题!

library(dplyr)

data <- data_frame(
  Date = c("7/16","8/16","8/16","8/16","9/16","9/16"),
  Region = c("NW", "NW", "SW", "SW", "NW", "NW"),
  Company = c("ABC", "ABC", "DEF", "DEF", "ABC", "DEF"),
  Item = c("Phone", "Phone", "Food", "Food", "Tools", "Tools"),
  Price = c(200, 200, 100, 50, 100, 50)
  )

data %>% 
  group_by(Region, Company, Item) %>% 
  mutate(Price = Price + mean(Price))

输出如下:

Source: local data frame [6 x 5]
Groups: Region, Company, Item [4]
   Date Region Company  Item Price
  <chr>  <chr>   <chr> <chr> <dbl>
1  7/16     NW     ABC Phone   400
2  8/16     NW     ABC Phone   400
3  8/16     SW     DEF  Food   175
4  8/16     SW     DEF  Food   125
5  9/16     NW     ABC Tools   200
6  9/16     NW     DEF Tools   100

【讨论】:

  • 如果您需要一个比 Price + mean(Price) 更复杂的函数,您可以使用 dpurrrlyr 库中的 by_slice 或编写自己的函数并将其输入 mutate 或 @987654327 @如果你想获得不同的组。
  • 谢谢,这看起来棒极了!是否可以输入一个非常复杂的函数,例如将异常值修剪为mutate,或者使用by_slice 更可取?
  • 是的,只需定义您的函数,然后从 mutate 中调用它。请注意,当您在 mutate 中调用 df 的 var 时,它将以 vector 的形式出现,即分组的长度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多