【问题标题】:R: Conditional row sum for data frame based on conditions in another data frameR:基于另一个数据帧中的条件的数据帧的条件行总和
【发布时间】:2021-02-04 06:24:15
【问题描述】:

我有一个数据框dfcompanies,其中列出了大约 6000 家公司,其标识代码为indentifier,他们的行业industry 以及他们在 132 个不同类别中的得分(NA, 0, or 1),例如category1-4:

> dfcompanies

    identifier  industry            category1   category2   category3   category4

1   MBWS.PA     Alcoholic Beverages 1           0           1           1
2   KAER.VI     Commercial Banks    0           1           0           1
3   TIRO.VI     Commercial Banks    1           NA          1           0
4   EVNV.VI     Power Generation    0           1           1           1
5   MANV.VI     Processed Foods     NA          0           NA          NA
6   LENV.VI     Chemical            1           NA          1           1

我还有第二个数据框,dfmatcategories,它定义了industry 中存在的所有行业;在industrymat 列中列出;他们的材料类别在categorymat,并在第三列描述类别type(strength, or concern)

> dfmatcategories

    industrymat         categorymat type

1   Alcoholic Beverages category1   concern
2   Alcoholic Beverages category2   strength
3   Alcoholic Beverages category3   strength
4   Insurance           category100 strength
5   Insurance           category99  strength
6   Chemical            category1   concern

理想情况下,我想为dfcompanies 中的每个公司获取在categorymat 中定义的材料类别中收到的积分总和,这些材料类别在新列sum_mat 中添加了type strengthdfcompanies

> dfcompanies

    identifier  industry            category1   category2   category3   category4   sum_mat

1   MBWS.PA     Alcoholic Beverages 1           0           1           1           1
2   KAER.VI     Commercial Banks    0           1           0           1           5
3   TIRO.VI     Commercial Banks    1           NA          1           0           3
4   EVNV.VI     Power Generation    0           1           1           1           4
5   MANV.VI     Processed Foods     NA          0           NA          NA          1
6   LENV.VI     Chemical            1           NA          1           1           0

示例:

dfcompaniesindentifierMBWS.PA的公司属于industryAlcoholic Beverages并获得分数:1category1,01,@987654 @ 在category3 中,还有1category4 中。

dfmatcategoriesindustrymatAlcoholic Beverages1-3 在列 categorymat 中仅列出 category1category2category3 作为材料类别。

但是,只有category2category3 属于type strength

因此对于MBWS.PAsum_mat => 1 =0(得分category2+ 1(得分category3)。

不幸的是,我是 R 新手,完全不知道如何解决这个问题。

有人可以帮帮我吗?

最好的问候 托马斯

【问题讨论】:

  • 我无法理解您如何计算 sum_mat,如何获得值 1,5,3 等等。这些计算值是针对您的原始数据框还是此处给出的示例?
  • 为了说明,我为 MBWS.PA 添加了 sum_mat 的计算。给出的数据仅用于说明,MBWS.PA的sum_mat以外的其他值无法手动计算。

标签: r dataframe sum conditional-statements


【解决方案1】:

以下基于 tidyverse 的解决方案通过旋转数据来解决问题。

library(dplyr)
library(tidyr)

dfcompanies %>%
  full_join(dfmatcategories, by = c('industry' = 'industrymat')) %>%
  filter(!identifier %in% NA) %>%
  pivot_longer(category1:category4) %>%
  mutate(sum_mat = if_else(categorymat == name & 
                           type =='strength' &
                           value == 1, 1, 0)) %>%
  pivot_wider(names_from = name, values_from = value) %>%
  group_by(identifier) %>%
  mutate(sum_mat = sum(sum_mat)) %>%
  slice(1) %>%
  ungroup() %>%
  select(colnames(dfcompanies), sum_mat)

# # A tibble: 6 x 7
#   identifier industry            category1 category2 category3 category4 sum_mat
#   <chr>      <chr>                   <dbl>     <dbl>     <dbl>     <dbl>   <dbl>
# 1 EVNV.VI    Power Generation            0        NA        NA        NA      NA
# 2 KAER.VI    Commercial Banks            0        NA         0        NA      NA
# 3 LENV.VI    Chemical                    1        NA         1         1       0
# 4 MANV.VI    Processed Foods            NA        NA        NA        NA      NA
# 5 MBWS.PA    Alcoholic Beverages         1         1         1         1       2
# 6 TIRO.VI    Commercial Banks            1        NA         1        NA      NA

数据

dfcompanies <- structure(list(identifier = c("MBWS.PA", "KAER.VI", "TIRO.VI", 
"EVNV.VI", "MANV.VI", "LENV.VI"), industry = c("Alcoholic Beverages", 
"Commercial Banks", "Commercial Banks", "Power Generation", "Processed Foods", 
"Chemical"), category1 = c(1, 0, 1, 0, NA, 1), category2 = c(1, 
1, NA, 1, 0, NA), category3 = c(1, 0, 1, 1, NA, 1), category4 = c(1, 
1, 0, 1, NA, 1)), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

dfmatcategories <- structure(list(industrymat = c("Alcoholic Beverages", "Alcoholic Beverages", 
"Alcoholic Beverages", "Insurance", "Insurance", "Chemical"), 
    categorymat = c("category1", "category2", "category3", "category100", 
    "category99", "category1"), type = c("concern", "strength", 
    "strength", "strength", "strength", "concern")), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

【讨论】:

  • 谢谢!您的解决方案让我完成了大约 90% 的工作。不幸的是,我没有在我的示例中介绍完整的工作流程。一旦dfcompanies 的公司在category1-4 中的任何一个中获得0, or NA 的分数,我就会遇到问题,该分数被定义为industrymat 下的industrytype strength 的材料。然后,该公司在其sum_mat 中获得1,即使它的得分是0, or NA
  • 非常欢迎您@NeuThomas95。我已经编辑了我的答案。我希望它现在对你有用。
  • 再次感谢@rjen!我对您的代码做了一个小补充:mutate(sum_mat = sum(sum_mat, na.rm = TRUE)) 现在NA 材料categories1-4 的值被视为0 用于sum。我将新代码应用于原始数据,一切顺利!
猜你喜欢
  • 2018-10-03
  • 2013-02-09
  • 1970-01-01
  • 2021-09-04
  • 2023-03-27
  • 2017-11-10
  • 2018-01-28
  • 2013-06-14
  • 2021-08-18
相关资源
最近更新 更多