如果特定列的变量相同,是否可以将多个列加在一起?

时间:2019-06-17 23:56:57

标签: r dataframe tibble

我无法弄清楚如何将变量分组在一起。例如,我想对所有candy1求平均值,其中〜COUNTRY数据列为“美国”或“加拿大”或“英国”。同时删除/忽略所有包含NA(null?)的行

注意:我要为数据帧执行的操作超过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)

“美国,加拿大和英国”代表“美国”,“加拿大”和“英国”的总体平均水平。

真的没有任何错误消息,因为我还没有找到实现它的方法。

2 个答案:

答案 0 :(得分:1)

一种解决方案:使用tidyr::gather将数据从“宽”格式更改为“长”格式,以为变量名创建一列,为值创建一列。然后,您可以使用dplyr::group_by国家和变量名,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

答案 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