r语言 - 在数据帧中创建一个新变量,该变量包含所有其他组的值之和



我有类似的数据

example_data <- data.frame(
company   = c(rep("A",6),
rep("B",6),
rep("C",6)),
year      = c(rep(c(rep(c(2019), 3), rep(2020, 3)), 3)),
country   = c(rep(c("Australia","Tanzania","Nepal"),3)),
sales     = c(sample(1000:2000, 18)),
employees = c(sample(100:200, 18)),
profit    = c(sample(500:1000, 18))
)

打印出来的时候是这样的:

> example_data
company year   country sales employees profit
1        A 2019 Australia  1815       138    986
2        A 2019  Tanzania  1183       126    907
3        A 2019     Nepal  1159       155    939
4        A 2020 Australia  1873       183    866
5        A 2020  Tanzania  1858       198    579
6        A 2020     Nepal  1841       184    601
7        B 2019 Australia  1989       160    595
8        B 2019  Tanzania  1162       151    520
9        B 2019     Nepal  1470       187    670
10       B 2020 Australia  1013       128    945
11       B 2020  Tanzania  1718       123    886
12       B 2020     Nepal  1135       149    778
13       C 2019 Australia  1846       188    755
14       C 2019  Tanzania  1445       194    916
15       C 2019     Nepal  1029       145    903
16       C 2020 Australia  1737       161    578
17       C 2020  Tanzania  1489       141    859
18       C 2020     Nepal  1350       167    536

三个感兴趣的变量sales,employees,profit的观测单位是company,year,country的唯一组合。

我需要的是数据框架中的一列,分别对应这三个名为other_salesother_employeesother_profit的变量。(在我的实际数据中,我有近40个感兴趣的变量,而不是只有3个。)这些应该是当年其他公司的总和,在那个国家,对于这个变量。例如,example_data$other_sales[1]应该是两个值1989和1846的和,即"公司B在该country中的yearsales,公司C在该country中的yearsales"。

我熟悉dplyr::group_by()dplyr::mutate(),但我很难想出一个解决这个问题的方法。我想做的是像这样:

library(dplyr)
example_data %>%
group_by(company, year, country) %>%
mutate(other_sales = sum(
example_data %>% filter(company!="this") %>% .$sales)
)
# "this" should be the value of 'company' in the current group

显然,这段代码不起作用。即使这样做,也无法实现为数据帧中的每个指定列自动创建这些other_*变量的目标。我想过创建一个复杂的for循环,但我想在我沿着这个最可能错误的路线前进之前,最好在这里问一下。最后,虽然可以构建一个纯粹基于列索引的解决方案(即,对于example_data[1,7]计算[7,4]和[13,4]的和),但这在我的实际数据中不起作用,因为每个公司的观察数量可能不同。

编辑:代码中的小更正

——SOLUTION——根据这个问题下面的评论,我想出了一个解决问题的方法:

example_data %>%
group_by(year, country) %>%
mutate(across(sales:profit, .names = "other_{.col}", function(x) sum(x)-x))

我想这会解决你的问题。

example_data %>% 
group_by(country,year) %>% 
mutate(other_sales = sum(sales)- sales)

将其推广到所有变量,即销售额,利润和员工:

(arrange不是必需的,但有助于检查)

library(tidyverse)
set.seed(123)
example_data <- data.frame(
company   = c(rep("A",6),
rep("B",6),
rep("C",6)),
year      = c(rep(c(rep(c(2019), 3), rep(2020, 3)), 3)),
country   = c(rep(c("Australia","Tanzania","Nepal"),3)),
sales     = c(sample(1000:2000, 18)),
employees = c(sample(100:200, 18)),
profit    = c(sample(500:1000, 18))
)
example_data |> 
arrange(country, year, company) |> # Optional 
group_by(country, year) |> 
mutate(across(sales:profit, ~sum(.) - ., .names = "other_{.col}"))
#> # A tibble: 18 × 9
#> # Groups:   country, year [6]
#>    company  year country   sales employees profit other_sales other_em…¹ other…²
#>    <chr>   <dbl> <chr>     <int>     <int>  <int>       <int>      <int>   <int>
#>  1 A        2019 Australia  1414       190    989        3190        302    1515
#>  2 B        2019 Australia  1817       125    522        2787        367    1982
#>  3 C        2019 Australia  1373       177    993        3231        315    1511
#>  4 A        2020 Australia  1525       108    892        2830        372    1524
#>  5 B        2020 Australia  1228       197    808        3127        283    1608
#>  6 C        2020 Australia  1602       175    716        2753        305    1700
#>  7 A        2019 Nepal      1178       191    762        2899        283    1608
#>  8 B        2019 Nepal      1298       141    943        2779        333    1427
#>  9 C        2019 Nepal      1601       142    665        2476        332    1705
#> 10 A        2020 Nepal      1937       171    829        2721        266    1967
#> 11 B        2020 Nepal      1013       135    991        3645        302    1805
#> 12 C        2020 Nepal      1708       131    976        2950        306    1820
#> 13 A        2019 Tanzania   1462       156    608        2781        286    1633
#> 14 B        2019 Tanzania   1117       106    910        3126        336    1331
#> 15 C        2019 Tanzania   1664       180    723        2579        262    1518
#> 16 A        2020 Tanzania   1194       192    924        3010        296    1423
#> 17 B        2020 Tanzania   1243       182    634        2961        306    1713
#> 18 C        2020 Tanzania   1767       114    789        2437        374    1558
#> # … with abbreviated variable names ¹​other_employees, ²​other_profit

创建于2012-12-08与reprex v2.0.2

最新更新