首页 > 解决方案 > 如何根据 R 中的映射文件迭代一个数据帧?

问题描述

序列号。 公司 1 公司 2 公司 3
01 不适用 2 不适用
02 2 不适用 5
03 不适用 不适用 4
04 1 不适用 不适用
05 不适用 4 不适用

我有一个这样的数据结构,其中列标题代表一些公司,行标题代表购买产品的消费者。“NA”代表消费者没有购买该公司的产品。我有第二个映射文件,其中公司表示为行标题,如下所示 -

公司 国家 类别
公司 1 英国 快消品
公司 2 英国 快消品
公司 3 印度 快消品
公司 4 我们 尼古丁

该数据集针对 10000 多名消费者和 1000 家公司。我正在使用聚合函数和映射文件获得不同国家和类别的市场份额。我想看看在第一个数据框中迭代值以更改不同国家和类别的份额。这个想法是创建一个循环,我可以选择哪个国家(或类别)的份额需要与份额一起更改,然后使用映射文件来迭代这些国家(或类别)中公司的值。只有那些从属于该国家(或类别)的公司购买产品的消费者才需要更改这些值。

有人可以建议如何在 R(最好)或 Python 中完成此操作吗?

编辑:在迭代之前,我将使用 R 中的聚合函数来获取这样的国家(或类别)的份额 -

国家 分享
英国 0.33
我们 0.02
0.41
红外 0.11
PK 0.13

在循环中,我希望能够将某个国家(例如英国)的份额指定为所需的任何内容(例如 0.5)。映射文件将用于将值迭代到人们从英国公司购买产品的第一个数据结构。

最终输出将是这样的。

国家 分享
英国 0.50
我们 0.00
0.38
红外 0.11
PK 0.01

标签: rdataframeloops

解决方案


这里有一个猜测:最终,这是一个从宽到长的重塑组合,然后是merge/join,最后是按组聚合/汇总。如果您需要有关任一操作的更多信息,使用这些关键字(在 SO 上)将提供非常有用的信息。

基数 R (和reshape2)

## reshape
dat1melted <- reshape2::melt(dat1, "Serial No.", variable.name = "Company")
dat1melted$Company <- as.character(dat1melted$Company)
dat1melted <- dat1melted[!is.na(dat1melted$value),]
dat1melted
#    Serial No.   Company value
# 2          02 Company 1     2
# 4          04 Company 1     1
# 6          01 Company 2     2
# 10         05 Company 2     4
# 12         02 Company 3     5
# 13         03 Company 3     4

## merge
dat1merged <- merge(dat1melted, dat2, by = "Company", all.x = TRUE)
dat1merged
#     Company Serial No. value Country Category
# 1 Company 1         02     2      UK     FMCG
# 2 Company 1         04     1      UK     FMCG
# 3 Company 2         01     2      UK     FMCG
# 4 Company 2         05     4      UK     FMCG
# 5 Company 3         02     5   India     FMCG
# 6 Company 3         03     4   India     FMCG

## aggregate by group
aggregate(value ~ Country, data = dat1merged, FUN = sum)
#   Country value
# 1   India     9
# 2      UK     9

dplyr

library(dplyr)
# library(tidyr) # pivot_longer
dat1 %>%
  ## reshape
  tidyr::pivot_longer(-`Serial No.`, names_to = "Company") %>%
  filter(!is.na(value)) %>%
  ## merge
  left_join(., dat2, by = "Company") %>%
  ## aggregate by group
  group_by(Country) %>%
  summarize(value = sum(value))
# # A tibble: 2 x 2
#   Country value
#   <chr>   <int>
# 1 India       9
# 2 UK          9

推荐阅读