我很难弄清楚如何将变量组合在一起。 例如,我想平均所有 candy1,其中数据列 ~COUNTRY 是"美国"或"加拿大"或"英国"。 同时删除/省略包含 NA(空?
注意:我尝试为数据框执行的操作有超过 2000 行和 140 列。
考虑过使用 for 循环,但无法弄清楚如何正确执行此操作。
Candy_Hierarchy <- tribble(~COUNTRY, ~candy1, ~candy2, ~candy3,
'United States',2, 0, 1,
'United States', 1, 2, 0,
'United States',2, 1, 2,
'Canada', NA, NA, NA,
'Canada', 2, 0, 1,
'United Kingdom', 1, 2, 0)
到
Candy_Hierarchy <- tribble(~COUNTRY, ~candy1, ~candy2, ~candy3,
'US, Canada, and UK', 1.6, 1, 0.8,
'United States',1.67, 1, 1,
'Canada', 2, 0, 1,
'United Kingdom', 1, 2, 0)
"美国、加拿大和英国">表示"美国"、"加拿大"和"英国"的整体平均值。
真的没有任何错误消息,因为我无法找到实现它的方法。
一种解决方案:使用 tidyr::gather
将数据从"宽"更改为"长"格式,为变量名创建一列,为值创建一列。然后,您可以dplyr::group_by
COUNTRY 和变量名称,dplyr::summarise
以获取平均值,tidyr::spread
转换回宽格式。
library(dplyr)
library(tidyr)
tribble(~COUNTRY, ~candy1, ~candy2, ~candy3,
'United States',2, 0, 1,
'United States', 1, 2, 0,
'United States',2, 1, 2,
'Canada', NA, NA, NA,
'Canada', 2, 0, 1,
'United Kingdom', 1, 2, 0) %>%
gather(Var, Val, -COUNTRY) %>%
group_by(COUNTRY, Var) %>%
summarise(Mean = mean(Val, na.rm = TRUE)) %>%
spread(Var, Mean)
结果:
# A tibble: 3 x 4
# Groups: COUNTRY [3]
COUNTRY candy1 candy2 candy3
<chr> <dbl> <dbl> <dbl>
1 Canada 2 0 1
2 United Kingdom 1 2 0
3 United States 1.67 1 1
这是执行此操作的一种方法。我们可以使用filter_at(vars(starts_with("candy")), all_vars(is.na(.)))
删除具有所有NA
的行。在summarize
操作之后,我们可以使用 bind_rows
将这些行添加回来。
library(tidyverse)
Candy_Hierarchy2 <- Candy_Hierarchy %>% rowid_to_column()
Candy_allNA <- Candy_Hierarchy2 %>%
filter_at(vars(starts_with("candy")), all_vars(is.na(.)))
Candy_Hierarchy3 <- Candy_Hierarchy2 %>%
anti_join(Candy_allNA, by = "rowid") %>%
group_by(COUNTRY) %>%
summarise_at(vars(starts_with("candy")), list(~mean(., na.rm = TRUE))) %>%
ungroup() %>%
bind_rows(
Candy_allNA %>% select(-rowid)
) %>%
arrange(COUNTRY)
Candy_Hierarchy3
# # A tibble: 4 x 4
# COUNTRY candy1 candy2 candy3
# <chr> <dbl> <dbl> <dbl>
# 1 Canada 2 0 1
# 2 Canada NA NA NA
# 3 United Kingdom 1 2 0
# 4 United States 1.67 1 1
更新
如果不需要保留所有NA
行,则此操作在tidyverse
下变得非常容易。
Candy_Hierarchy4 <- Candy_Hierarchy %>%
group_by(COUNTRY) %>%
summarise_at(vars(starts_with("candy")), list(~mean(., na.rm = TRUE))) %>%
ungroup()
Candy_Hierarchy4
# # A tibble: 3 x 4
# COUNTRY candy1 candy2 candy3
# <chr> <dbl> <dbl> <dbl>
# 1 Canada 2 0 1
# 2 United Kingdom 1 2 0
# 3 United States 1.67 1 1