我发现dplyr快速,简单地汇总和汇总数据。但是我找不到使用dplyr解决以下问题的方法。
给出以下数据帧:
df_2017 <- data.frame(
expand.grid(1:195,1:65,1:39),
value = sample(1:1000000,(195*65*39)),
period = rep("2017",(195*65*39)),
stringsAsFactors = F
)
df_2017 <- df_2017[sample(1:(195*65*39),450000),]
names(df_2017) <- c("company", "product", "acc_concept", "value", "period")
df_2017$company <- as.character(df_2017$company)
df_2017$product <- as.character(df_2017$product)
df_2017$acc_concept <- as.character(df_2017$acc_concept)
df_2017$value <- as.numeric(df_2017$value)
ratio_df <- data.frame(concept=c("numerator","numerator","numerator","denom", "denom", "denom","name"),
ratio1=c("1","","","4","","","Sales over Assets"),
ratio2=c("1","","","5","6","","Sales over Expenses A + B"), stringsAsFactors = F)
df_2017中的列为:
expand.grid暗示,公司-产品-acc_concept 的组合永远不会重复,但是,可能会发生某些主题没有每个公司-产品-acc_concept 的情况。 em>组合。这就是代码行“ df_2017 <-df_2017 [sample(1:195 * 65 * 39),450000),]”的原因,也是输出可能变为NA的原因(见下文)。
ratio_df中的列在哪里:
我想为每个公司内的每种产品计算acc_concept之间的2个比率(ratio_df)。
例如:
我从ratio_df中获取第一个比率“ acc_concepts”和“ name”:
num_acc_concept <- ratio_df[ratio_df$concept == "numerator", 2]
denom_acc_concept <- ratio_df[ratio_df$concept == "denom", 2]
ratio_name <- ratio_df[ratio_df$concept == "name", 2]
然后我计算一家公司的一种产品的比率,只是为了表明您想要我要做的事情:
ratio1_value <- sum(df_2017[df_2017$company == 1 & df_2017$product == 1 & df_2017$acc_concept %in% num_acc_concept, 4]) / sum(df_2017[df_2017$company == 1 & df_2017$product == 1 & df_2017$acc_concept %in% denom_acc_concept, 4])
输出:
output <- data.frame(Company="1", Product="1", desc_ratio=ratio_name, ratio_value = ratio1_value, stringsAsFactors = F)
就像我之前说的,我想为每个公司的每个产品做到这一点
输出data.frame可能是类似的东西(比率不是真正的比率,因为我还没有完成计算):
company product desc_ratio ratio_value
1 1 Sales over Assets 0.9303675
1 2 Sales over Assets 1.30
1 3 Sales over Assets Nan
1 4 Sales over Assets Inf
1 5 Sales over Assets 2.32
1 6 Sales over Assets NA
.
.
.
1 1 Sales over Expenses A + B 3.25
.
.
.
2 1 Sales over Assets 0.256
以此类推...
我希望这次我已经说清楚了:)
有什么方法可以用dplyr解决此行问题吗?我应该将df_2017进行变异吗?在这种情况下,哪种铸造方法是最好的?
欢迎任何帮助!
答案 0 :(得分:1)
这是一种实现方式。最后,我将代码计时到了所有记录上。
首先创建一个函数来创建所有比率。请注意,此功能仅在dplyr代码内有用。
ratio <- function(data){
result <- data.frame(desc_ratio = rep(NA, ncol(ratio_df) -1), ratio_value = rep(NA, ncol(ratio_df) -1))
for(i in 2:ncol(ratio_df)){
num <- ratio_df[ratio_df$concept == "numerator", i]
denom <- ratio_df[ratio_df$concept == "denom", i]
result$desc_ratio[i-1] <- ratio_df[ratio_df$concept == "name", i]
result$ratio_value[i-1] <- sum(ifelse(data$acc_concept %in% num, data$value, 0)) / sum(ifelse(data$acc_concept %in% denom, data$value, 0))
}
return(result)
}
使用dplyr,tidyr和purrr将所有内容放在一起。首先对数据进行分组,嵌套函数所需的数据,然后对嵌套数据进行mutate操作。删除不需要的嵌套数据和嵌套以获取所需的输出。我将整理工作交给您。
library(dplyr)
library(purrr)
library(tidyr)
output <- df_2017 %>%
group_by(company, product, period) %>%
nest() %>%
mutate(ratios = map(data, ratio)) %>%
select(-data) %>%
unnest
output
# A tibble: 25,350 x 5
company product period desc_ratio ratio_value
<chr> <chr> <chr> <chr> <dbl>
1 103 2 2017 Sales over Assets 0.733
2 103 2 2017 Sales over Expenses A + B 0.219
3 26 26 2017 Sales over Assets 0.954
4 26 26 2017 Sales over Expenses A + B 1.01
5 85 59 2017 Sales over Assets 4.14
6 85 59 2017 Sales over Expenses A + B 1.83
7 186 38 2017 Sales over Assets 7.85
8 186 38 2017 Sales over Expenses A + B 0.722
9 51 25 2017 Sales over Assets 2.34
10 51 25 2017 Sales over Expenses A + B 0.627
# ... with 25,340 more rows
以system.time
为单位在我的计算机上运行此代码所花费的时间:
user system elapsed
6.75 0.00 6.81