【问题标题】:Reshape data to find number of missing record/value in each category based on reference variable in R根据 R 中的参考变量,重塑数据以查找每个类别中缺失记录/值的数量
【发布时间】:2021-05-16 05:24:39
【问题描述】:

我有家庭层面的人口普查数据。数据结构是这样的:记录第一个家庭规模,并根据该家庭成员的出生日期、教育程度、工作状况和其他个人人口统计信息收集每个成员。

这是一个家庭最多 4 名成员的虚拟样本,只有出生日期和工作状态(真实数据有家庭最多 10 名成员和 8 个演示)

df <- tibble::tribble(
  ~id, ~House_member, ~dob_1, ~dob_2, ~dob_3, ~dob_4, ~work_1, ~work_2, ~work_3, ~work_4,
   1L,            4L,  1983L,  1980L,  2009L,     NA,      2L,        2L,      NA,      NA,
   2L,            1L,  1940L,     NA,     NA,     NA,      9L,        NA,      NA,      NA,
   3L,            2L,  1951L,  1951L,     NA,     NA,      9L,        9L,      NA,      NA,
   4L,            4L,  1965L,  1973L,  2002L,     NA,      2L,        2L,      8L,      2L,
   5L,            3L,  1965L,  1948L,  2006L,     NA,      2L,        9L,      NA,      NA,
   6L,            1L,  1951L,     NA,     NA,     NA,      9L,        NA,      NA,      NA,
   7L,            1L,  1955L,     NA,     NA,     NA,     10L,        NA,      NA,      NA,
   8L,            4L,  1982L,  1978L,  2008L,     NA,      2L,        2L,      NA,      NA,
   9L,            2L,  1990L,  1997L,     NA,     NA,      2L,        8L,      NA,      NA,
  10L,            2L,  1953L,  1957L,     NA,     NA,      2L,        2L,      NA,      NA
  )


df 
# A tibble: 10 x 10
      id House_member dob_1 dob_2 dob_3 dob_4 work_1 work_2 work_3 work_4
   <int>        <int> <int> <int> <int> <lgl>  <int>    <int>  <int> <lgl> 
 1     1            4  1983  1980  2009 NA         2        2     NA NA    
 2     2            1  1940    NA    NA NA         9       NA     NA NA    
 3     3            2  1951  1951    NA NA         9        9     NA NA    
 4     4            4  1965  1973  2002 NA         2        2      8 2    
 5     5            3  1965  1948  2006 NA         2        9     NA NA    
 6     6            1  1951    NA    NA NA         9       NA     NA NA    
 7     7            1  1955    NA    NA NA        10       NA     NA NA    
 8     8            4  1982  1978  2008 NA         2        2     NA NA    
 9     9            2  1990  1997    NA NA         2        8     NA NA    
10    10            2  1953  1957    NA NA         2        2     NA NA 

我正在寻找一种方法来查找每个类别(出生日期、工作状态)有多少家庭缺少一些成员信息并总结/报告。我不确定从这个数据结构中提取这种洞察力的最佳方法是什么

例如查看样本数据,id == 1 是 4 个家庭成员,但缺少 dob_4(此 HH 缺少 work_4)id = 4 和 dob_4 等同样的问题。

我找到了 this 旧帖子,但这正是我要找的。​​p>

【问题讨论】:

  • work_1_2 列的原因是什么?即为什么不是work_2???
  • 这是错字。我修好了。
  • 另请注意,您的数据实际上有 work_4id = 4 的数据,但您没有在下面显示。

标签: r dplyr tidyverse data-cleaning


【解决方案1】:

dplyr + tidyr 解决方案的扩展变体给出了缺失值的 id 和 person_id:

df <- tibble::tribble(
  ~id, ~House_member, ~dob_1, ~dob_2, ~dob_3, ~dob_4, ~work_1, ~work_2, ~work_3, ~work_4,
  1L,            4L,  1983L,  1980L,  2009L,     NA,      2L,        2L,      NA,      NA,
  2L,            1L,  1940L,     NA,     NA,     NA,      9L,        NA,      NA,      NA,
  3L,            2L,  1951L,  1951L,     NA,     NA,      9L,        9L,      NA,      NA,
  4L,            4L,  1965L,  1973L,  2002L,     NA,      2L,        2L,      8L,      2L,
  5L,            3L,  1965L,  1948L,  2006L,     NA,      2L,        9L,      NA,      NA,
  6L,            1L,  1951L,     NA,     NA,     NA,      9L,        NA,      NA,      NA,
  7L,            1L,  1955L,     NA,     NA,     NA,     10L,        NA,      NA,      NA,
  8L,            4L,  1982L,  1978L,  2008L,     NA,      2L,        2L,      NA,      NA,
  9L,            2L,  1990L,  1997L,     NA,     NA,      2L,        8L,      NA,      NA,
  10L,            2L,  1953L,  1957L,     NA,     NA,      2L,        2L,      NA,      NA
)



library(dplyr)
library(tidyr)

df %>% 
  pivot_longer(cols = matches("dob|work"),
               names_to = c("name", "person"),
               names_sep = "_") %>% 
  group_by(id, name) %>% 
  filter(person <= max(House_member)) %>% 
  filter(is.na(value)) %>% 
  select(id, name, person) %>% 
  arrange(id, name)

返回:

# A tibble: 8 x 3
# Groups:   id, name [6]
  id name  person
  <int> <chr> <chr> 
1     1 dob   4     
2     1 work  3     
3     1 work  4     
4     4 dob   4     
5     5 work  3     
6     8 dob   4     
7     8 work  3     
8     8 work  4

【讨论】:

    【解决方案2】:

    以更长的格式重塑数据。使用 values_drop_na = TRUE 删除 NA 值。现在我们可以通过每个id 中的行数减去House_member 值来找出缺失的信息。

    library(dplyr)
    library(tidyr)
    
    df %>%
      pivot_longer(cols = matches('dob|work'), 
                  names_to = c('.value', 'member_num'), 
                  names_sep = '_',
                  values_drop_na = TRUE) 
      group_by(id) %>%
      summarise(missing_info = first(House_member) - n())
    
    #      id missing_info
    # * <int>        <int>
    # 1     1            1
    # 2     2            0
    # 3     3            0
    # 4     4            0
    # 5     5            0
    # 6     6            0
    # 7     7            0
    # 8     8            1
    # 9     9            0
    #10    10            0
    

    要获取 dob 的缺失值并单独工作,我们可以这样做:

    df %>%
      pivot_longer(cols = matches('dob|work'), 
                   names_to = c('.value', 'member_num'), 
                   names_sep = '_', 
                   values_drop_na = TRUE) %>%
      group_by(id) %>%
      summarise(across(c(dob, work), ~first(House_member) - n() + sum(is.na(.)), 
                .names = 'missing_{col}'))
    
    #     id  missing_date missing_work
    # * <int>        <int>        <int>
    # 1     1            1            2
    # 2     2            0            0
    # 3     3            0            0
    # 4     4            1            0
    # 5     5            0            1
    # 6     6            0            0
    # 7     7            0            0
    # 8     8            1            2
    # 9     9            0            0
    #10    10            0            0
    

    【讨论】:

    • 感谢@ronak 最后您的方法,我们每个 id 只有missing_info。我们不知道是否缺少出生日期或工作等,除非我们一一使用它:每个类别的匹配('dob')。正确吗?
    • 添加更新以找出每个id@DanielG 的缺失日期或工作。
    猜你喜欢
    • 2020-08-21
    • 2019-01-16
    • 2014-10-04
    • 1970-01-01
    • 2012-09-08
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    相关资源
    最近更新 更多