Подсчитать или суммировать значения 2 столбцов на основе значения другого столбца в том же кадре данных - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть датафрейм ниже:

year<-c("2000","2000","2001","2002","2000","2002")
gender<-c("M","F","M","F","M","M")
weight<-c(0.5,0.7,0.8,0.7,0.6,0.9)
YG<-data.frame(year,gender,weight)

, и я хочу подсчитать gender за 2000 и 2001 годы и суммировать weight за 2002 год, чтобы создать новый фрейм данных, например:

year   M   F
1 2000 2.0 1.0
2 2001 1.0 0.0
3 2002 0.9 0.7

Я пробовал что-то вроде:

library(tidyverse)
YG %>%
  group_by(year) %>%
  summarise(sum(weight[year=="2002"]))%>%
  count(round(gender[year!="2002"])) %>%
  spread(gender, n, fill = 0)

Ответы [ 4 ]

0 голосов
/ 18 декабря 2018

Одной из возможностей является предварительная обработка того, как вы хотите справиться с «весом».По сути, вы хотите добавить веса для 2002 года, но добавить веса 1 для других лет.Сначала вы можете сделать это:

YG <- YG %>% add_column(wt = ifelse(year == 2002, weight, 1))

Затем вы можете агрегировать и использовать функцию dcast в пакете data.table, чтобы изменить порядок результатов.

YG %>% group_by(year, gender) %>% summarise(count = sum(wt)) %>% 
   dcast(formula = year~gender,fun.aggregate = sum,value.var = "count")

  year   F   M
1 2000 1.0 2.0
2 2001 0.0 1.0
3 2002 0.7 0.9
0 голосов
/ 18 декабря 2018

Учитывая ваши данные, вы можете использовать dcast:

library(data.table)
setDT(YG)
result <- dcast(YG,  year ~ gender, value.var = 'weight', fun = list(sum, length))
result[, .(year, 
           `F` = c(result$weight_length_F[1:2], result$weight_sum_F[3]),
           M = c(result$weight_length_M[1:2], result$weight_sum_M[3]))]

#year   F   M
#1: 2000 1.0 2.0
#2: 2001 0.0 1.0
#3: 2002 0.7 0.9

В качестве альтернативы, вы можете вызывать dcast два раза для наборов данных по годам, как показано ниже:

result2 <- rbindlist(list(
      dcast(YG[year != 2002], year ~ gender, value.var = 'weight', fun = length),
      dcast(YG[year == 2002], year ~ gender, value.var = 'weight', fun = sum)))

#   year   F   M
#1: 2000 1.0 2.0
#2: 2001 0.0 1.0
#3: 2002 0.7 0.9
0 голосов
/ 18 декабря 2018

Из-за логики, которую вы используете, я думаю, что использование case_when() будет работать очень хорошо.Если вы установили логику перед суммированием, то все, что вам нужно сделать, это сложить два столбца:

library(tidyverse)
library(data.table)
YG %>% 
  mutate(Male = case_when(gender == 'F' ~ 0,
                          year %in% c('2000', '2001') & gender == 'M'~1,
                          TRUE~weight),
         Female = case_when(gender == 'M' ~ 0,
                            year %in% c('2000', '2001') & gender == 'F'~1,
                            TRUE~weight)) %>%
  group_by(year) %>%
  summarize(M = sum(Male),
            F = sum(Female))

Это даст вам то, что вы ищете:

  year   M   F
1 2000 2.0 1.0
2 2001 1.0 0.0
3 2002 0.9 0.7
0 голосов
/ 18 декабря 2018

Я верю, что теперь у меня все правильно.

library(tidyverse)

YG %>%
  group_by(year, gender) %>%
  summarise(n = sum(weight),
            g = n()) %>%
  mutate(n = ifelse(year == 2002, n, g)) %>%
  select(-g) %>%
  spread(gender, n, fill = 0)
## A tibble: 3 x 3
## Groups:   year [3]
#  year      F     M
#  <fct> <dbl> <dbl>
#1 2000    1     2  
#2 2001    0     1  
#3 2002    0.7   0.9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...