zastąpienie grupy na podstawie stanu

głosy
3

Mam data.frame ( df), patrz przykład, który zawiera informacje o osobach. Oparty na kolumnie klucza ( sleutel), wiem, że jeśli ludzie żyją ze sobą (np tworzą rodzinę), czy nie. Teraz trzeba utworzyć nowe kolumny z informacjami na temat „” głowy rodziny.

     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

Tak więc na przykład: rzędu 5, Kemel męskie i gzhfd 1 (= głowy rodziny Kemel). Jest żonaty z mrs. Boersma (ten sam klucz). Chcę mutować nową kolumnę ( lfthb) z wiekiem głowy rodziny dla wszystkich członków rodziny. Tak powinno stać coś takiego:

     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

Próbowałem wielu sposobów, z dplyrwykorzystaniem wielu kombinacjach group_by, case_wheni if_elseoświadczenia. I udało się zmutować kolumnę do głowy samej rodziny. Ale nie dla innych członków.

Na przykład, widocznie tylko zmienia wartość dla samej głowicy:

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

Ale jak obejmują gzhfd == 1po ~?

dput na przykład danych:

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)
Utwórz 19/12/2018 o 14:09
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
2

Kombinacja replacei ifelsebędzie wykonać zadanie, to znaczy,

library(tidyverse)

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

co daje,

# 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

Jak wspomina @Ronak możemy pominąć replaceczęść

df %>% 
 group_by(sleutel) %>% 
 mutate(lfthb = if (any(gzhfd == 1)) lft[gzhfd == 1] else NA)
Odpowiedział 19/12/2018 o 14:20
źródło użytkownik

głosy
0

Data.table podejście (wraca inf zamiast NA dla grupy z brak danych);

dt<-df %>% as.data.table() %>% 
  .[gzhfd==1, lfthb := lft, by="sleutel"] %>% 
  .[,lfthb:= max(lfthb,na.rm = T), by="sleutel"]
Odpowiedział 19/12/2018 o 15:06
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more