如何在 dplyr 中应用并创建一个新列
How to tapply in dplyr and create a new column
我被 dplyr 困住了(又一次!)并试图在不死于尝试的情况下解决我的问题。
我的 df 的第一行是这样的:
df <- structure(list(fecha = c(1990, 1990, 1990, 1990, 1990, 1990,
1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990), cientifico = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "Argentina sphyraena", class = "factor"),
dem_sect = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AB", "EP", "FE", "MF",
"PA"), class = "factor"), sector = c("EPb", "EPc", "EPc",
"EPb", "EPa", "EPa", "EPb", "EPc", "EPb", "EPb", "EPb", "EPb",
"EPb", "EPb", "EPa"), md_area = c(3010.44, 665.88, 665.88,
3010.44, 1273.65, 1273.65, 3010.44, 665.88, 3010.44, 3010.44,
3010.44, 3010.44, 3010.44, 3010.44, 1273.65), md_peso = c(1.42957605985037,
1.04499099099099, 1.04499099099099, 1.42957605985037, 1.24025925925926,
1.24025925925926, 1.42957605985037, 1.04499099099099, 1.42957605985037,
1.42957605985037, 1.42957605985037, 1.42957605985037, 1.42957605985037,
1.42957605985037, 1.24025925925926), dummy = c(4303.65295361596,
695.838601081081, 695.838601081081, 4303.65295361596, 1579.65620555556,
1579.65620555556, 4303.65295361596, 695.838601081081, 4303.65295361596,
4303.65295361596, 4303.65295361596, 4303.65295361596, 4303.65295361596,
4303.65295361596, 1579.65620555556)), row.names = c(NA, -15L
), class = "data.frame")
我正在尝试将此 sumsect <- tapply(md_peso * md_area, as.factor(substr(names(sector), 1, 2)), sum)
“翻译”成 dplyr。但是没有成功,尽管我尝试了很多方法。我添加了一列("dem_sect"),这将是as.factor(substr(names(sector), 1, 2))
的结果,试图解决问题,但我失败了。
所需的输出将是一个带有新列的数据框:"sumsect"(具有相同的值(在本例中为 6579.148(md_peso 的总和) * md_area 按部门 (1579.6562 + 4303.6530 + 695.8386))
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
1 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
2 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
3 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
4 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
5 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
6 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
7 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
8 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
9 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
10 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
11 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
12 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
13 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
14 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
15 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
我们非常欢迎任何提示。提前致谢
你可以改变然后总结 dummy
的 unique
值
df |>
mutate(sumsect = sum(unique(dummy)))
如果您依赖 md_area 和 md_peso,您可以使用:
df |>
mutate(sumsect = sum(unique(md_area * md_peso)))
如果您要使用 dpylr
,则不需要 tapply
。如果您要使用 dpylr
.
,则不需要 tapply
library(tidyverse)
df %>% # target dataframe
cbind( # we will join a value as a new column for every row
df %>% # work with dataframe df
group_by(sector) %>% # calculate by sector
summarise(sumsect = unique(md_area*md_peso)) %>% # the md_area*md _peso
ungroup() %>% # remove grouping
summarise(sumsect = sum(sumsect)) # sum the 3 calculated values
)
输出:
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
1 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
2 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
3 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
4 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
5 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
6 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
7 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
8 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
9 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
10 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
11 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
12 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
13 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
14 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
15 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
如果您可能希望通过分组的 cientifico
或 fecha
或两者来计算 sumsect
,您可以将它们分组。在你的例子中只有一个。
在您的示例中,您只有 1 个日期和 1 个科学家。如果您希望这些列的每个级别的 sumsect 都不同,请不要忘记也对这些列进行分组。
更新:看到@Jahi Zamy answer+1 也可以不使用分组:分组将有机会控制真实数据集中的不同组:
df %>%
mutate(sumsect = sum(unique( md_peso * md_area)))
第一个回答:
您可以使用 dplyr
这样做:诀窍是使用 group_by
,然后使用 ungroup()
并与 unique
值相加。如果您想对特定组求和,则使用 group_by
而不是 ungroup
所需的组:
df %>%
group_by(sector) %>%
mutate(y = md_peso * md_area) %>%
ungroup() %>%
mutate(sumsect = sum(unique(y)), .keep="unused")
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
<dbl> <fct> <fct> <chr> <dbl> <dbl> <dbl> <dbl>
1 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
2 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
3 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
4 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
5 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.
6 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.
7 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
8 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
9 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
10 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
11 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
12 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
13 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
14 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
15 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.
我被 dplyr 困住了(又一次!)并试图在不死于尝试的情况下解决我的问题。
我的 df 的第一行是这样的:
df <- structure(list(fecha = c(1990, 1990, 1990, 1990, 1990, 1990,
1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990), cientifico = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "Argentina sphyraena", class = "factor"),
dem_sect = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AB", "EP", "FE", "MF",
"PA"), class = "factor"), sector = c("EPb", "EPc", "EPc",
"EPb", "EPa", "EPa", "EPb", "EPc", "EPb", "EPb", "EPb", "EPb",
"EPb", "EPb", "EPa"), md_area = c(3010.44, 665.88, 665.88,
3010.44, 1273.65, 1273.65, 3010.44, 665.88, 3010.44, 3010.44,
3010.44, 3010.44, 3010.44, 3010.44, 1273.65), md_peso = c(1.42957605985037,
1.04499099099099, 1.04499099099099, 1.42957605985037, 1.24025925925926,
1.24025925925926, 1.42957605985037, 1.04499099099099, 1.42957605985037,
1.42957605985037, 1.42957605985037, 1.42957605985037, 1.42957605985037,
1.42957605985037, 1.24025925925926), dummy = c(4303.65295361596,
695.838601081081, 695.838601081081, 4303.65295361596, 1579.65620555556,
1579.65620555556, 4303.65295361596, 695.838601081081, 4303.65295361596,
4303.65295361596, 4303.65295361596, 4303.65295361596, 4303.65295361596,
4303.65295361596, 1579.65620555556)), row.names = c(NA, -15L
), class = "data.frame")
我正在尝试将此 sumsect <- tapply(md_peso * md_area, as.factor(substr(names(sector), 1, 2)), sum)
“翻译”成 dplyr。但是没有成功,尽管我尝试了很多方法。我添加了一列("dem_sect"),这将是as.factor(substr(names(sector), 1, 2))
的结果,试图解决问题,但我失败了。
所需的输出将是一个带有新列的数据框:"sumsect"(具有相同的值(在本例中为 6579.148(md_peso 的总和) * md_area 按部门 (1579.6562 + 4303.6530 + 695.8386))
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
1 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
2 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
3 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
4 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
5 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
6 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
7 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
8 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
9 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
10 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
11 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
12 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
13 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
14 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
15 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
我们非常欢迎任何提示。提前致谢
你可以改变然后总结 dummy
的unique
值
df |>
mutate(sumsect = sum(unique(dummy)))
如果您依赖 md_area 和 md_peso,您可以使用:
df |>
mutate(sumsect = sum(unique(md_area * md_peso)))
如果您要使用 dpylr
,则不需要 tapply
。如果您要使用 dpylr
.
tapply
library(tidyverse)
df %>% # target dataframe
cbind( # we will join a value as a new column for every row
df %>% # work with dataframe df
group_by(sector) %>% # calculate by sector
summarise(sumsect = unique(md_area*md_peso)) %>% # the md_area*md _peso
ungroup() %>% # remove grouping
summarise(sumsect = sum(sumsect)) # sum the 3 calculated values
)
输出:
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
1 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
2 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
3 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
4 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
5 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
6 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
7 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
8 1990 Argentina sphyraena EP EPc 665.88 1.044991 695.8386 6579.148
9 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
10 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
11 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
12 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
13 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
14 1990 Argentina sphyraena EP EPb 3010.44 1.429576 4303.6530 6579.148
15 1990 Argentina sphyraena EP EPa 1273.65 1.240259 1579.6562 6579.148
如果您可能希望通过分组的 cientifico
或 fecha
或两者来计算 sumsect
,您可以将它们分组。在你的例子中只有一个。
在您的示例中,您只有 1 个日期和 1 个科学家。如果您希望这些列的每个级别的 sumsect 都不同,请不要忘记也对这些列进行分组。
更新:看到@Jahi Zamy answer+1 也可以不使用分组:分组将有机会控制真实数据集中的不同组:
df %>%
mutate(sumsect = sum(unique( md_peso * md_area)))
第一个回答:
您可以使用 dplyr
这样做:诀窍是使用 group_by
,然后使用 ungroup()
并与 unique
值相加。如果您想对特定组求和,则使用 group_by
而不是 ungroup
所需的组:
df %>%
group_by(sector) %>%
mutate(y = md_peso * md_area) %>%
ungroup() %>%
mutate(sumsect = sum(unique(y)), .keep="unused")
fecha cientifico dem_sect sector md_area md_peso dummy sumsect
<dbl> <fct> <fct> <chr> <dbl> <dbl> <dbl> <dbl>
1 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
2 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
3 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
4 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
5 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.
6 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.
7 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
8 1990 Argentina sphyraena EP EPc 666. 1.04 696. 6579.
9 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
10 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
11 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
12 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
13 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
14 1990 Argentina sphyraena EP EPb 3010. 1.43 4304. 6579.
15 1990 Argentina sphyraena EP EPa 1274. 1.24 1580. 6579.