заменить группы на основе условия - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть data.frame (df), см. Пример, который содержит информацию о людях.Исходя из ключевого столбца (sleutel), я знаю, живут ли люди вместе (например, создают ли они семью) или нет.Теперь мне нужно создать новые столбцы с информацией о «главе» семьи.

     name   sex gzverh   sleutel gzhfd lft
1 Loekens   Man      6  1847LS 9     3  49
2   Kemel Vrouw      5 1847LK 10     2  18
3   Kemel   Man      5 1847LK 10     2  22
4 Boersma Vrouw      4 1847LK 10     2  52
5   Kemel   Man      2 1847LK 10     1  54

Так, например: строка 5, Kemel, Male и gzhfd 1 (= глава семейства Kemel).Он женат на миссис.Бурсма (тот же ключ).Я хочу изменить новую колонку (lfthb) с указанием возраста главы семьи для всех членов семьи.Так должно получиться что-то вроде:

     name  sex  gzverh   sleutel gzhfd lft lfthb
1 Loekens   Man      6  1847LS 9     3  49    NA
2   Kemel Vrouw      5 1847LK 10     2  18    54
3   Kemel   Man      5 1847LK 10     2  22    54
4 Boersma Vrouw      4 1847LK 10     2  52    54
5   Kemel   Man      2 1847LK 10     1  54    54

Я пробовал несколько способов с dplyr, используя несколько комбинаций операторов group_by, case_when и if_else.И мне удается мутировать колонку для главы самой семьи.Но не для других членов.

Например, очевидно, изменяется только значение для самой головы:

df <- df %>% mutate(lfthb  = case_when(sleutel == lag(sleutel) & gzhfd == 1 ~ lft))

Но как включить gzhfd == 1 после ~?

dput данных примера:

structure(list(naam = c("Loekens", "Kemel", "Kemel", "Boersma", 
"Kemel"), gesl = c("Man", "Vrouw", "Man", "Vrouw", "Man"), gzverh = c(6L, 
5L, 5L, 4L, 2L), sleutel = c("1847LS 9", "1847LK 10", "1847LK 10", 
"1847LK 10", "1847LK 10"), gzhfd = c(3, 2, 2, 2, 1), lft = c(49, 
18, 22, 52, 54)), row.names = c(NA, 5L), class = "data.frame")

Ответы [ 2 ]

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

Подход data.table (возвращает -INF вместо NA для группы с отсутствующими данными):

dt<-df %>% as.data.table() %>% 
  .[gzhfd==1, lfthb := lft, by="sleutel"] %>% 
  .[,lfthb:= max(lfthb,na.rm = T), by="sleutel"]
0 голосов
/ 19 декабря 2018

Комбинация replace и ifelse сделает работу, т. Е.

library(tidyverse)

df %>% 
 group_by(sleutel) %>% 
 mutate(lfthb = ifelse(any(gzhfd == 1), replace(lft, gzhfd != 1, lft[gzhfd == 1]), NA))

, которая дает,

# A tibble: 5 x 7
# Groups:   sleutel [2]
  naam    gesl  gzverh sleutel   gzhfd   lft lfthb
  <chr>   <chr>  <int> <chr>     <dbl> <dbl> <dbl>
1 Loekens Man        6 1847LS 9      3    49    NA
2 Kemel   Vrouw      5 1847LK 10     2    18    54
3 Kemel   Man        5 1847LK 10     2    22    54
4 Boersma Vrouw      4 1847LK 10     2    52    54
5 Kemel   Man        2 1847LK 10     1    54    54

As @Ronakупоминает, что мы можем опустить replace часть

df %>% 
 group_by(sleutel) %>% 
 mutate(lfthb = if (any(gzhfd == 1)) lft[gzhfd == 1] else NA)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...