R - 用分组数据中的因子水平重新编码 NA
R - Recode NA with levels of a factor in grouped data
我有一个纵向结构的数据框如下:
df = structure(list(oslaua = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("E06000001", "E06000002",
"E06000003", "E06000004"), class = "factor"), wave = structure(c(1L,
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L), .Label = c("0",
"1", "2", "3"), class = "factor"), old.la = structure(c(1L, 1L,
NA, 1L, 2L, 2L, 2L, NA, 3L, 3L, 3L, 3L, 4L, 4L, NA), .Label = c("00EB",
"00EC", "00EE", "00EF"), class = "factor"), la = structure(c(1L,
1L, NA, 1L, 2L, 2L, 2L, NA, 3L, 3L, 3L, 3L, 4L, 4L, NA), .Label = c("Hartlepool UA",
"Middlesbrough UA", "Redcar and Cleveland UA", "Stockton-on-Tees UA"
), class = "factor"), dclg.code = structure(c(1L, 1L, NA, 1L,
4L, 4L, 4L, NA, 3L, 3L, 3L, 3L, 2L, 2L, NA), .Label = c("H0724",
"H0738", "V0728", "W0734"), class = "factor"), novo_entries = c(24L,
4L, 0L, 1L, 35L, 15L, 1L, 0L, 49L, 7L, 2L, 2L, 40L, 14L, 0L)), .Names = c("oslaua",
"wave", "old.la", "la", "dclg.code", "novo_entries"), row.names = c(NA,
15L), class = "data.frame")
我的标识符变量是 oslaua
,我的时间变量是 wave
。 old.la
、la
和 dclg.code
是具有 NA 的因子变量。我的
目标包括使用与每个标识符 (oslaua
) 关联的每个变量的级别重新编码我的 NA
。我尝试使用以下方法针对 old.la
的情况执行此操作:
df = df %>% group_by(oslaua) %>% mutate(old.la.1 = ifelse(is.na(old.la), unique(old.la), old.la)) %>% as.data.frame()
我部分明白了我的目的,但如您所见,存在一些问题:
> df
oslaua wave old.la la dclg.code novo_entries old.la.1
1 E06000001 0 00EB Hartlepool UA H0724 24 1
2 E06000001 1 00EB Hartlepool UA H0724 4 1
3 E06000001 2 <NA> <NA> <NA> 0 2
4 E06000001 3 00EB Hartlepool UA H0724 1 1
5 E06000002 0 00EC Middlesbrough UA W0734 35 2
6 E06000002 1 00EC Middlesbrough UA W0734 15 2
7 E06000002 2 00EC Middlesbrough UA W0734 1 2
8 E06000002 3 <NA> <NA> <NA> 0 2
9 E06000003 0 00EE Redcar and Cleveland UA V0728 49 3
10 E06000003 1 00EE Redcar and Cleveland UA V0728 7 3
11 E06000003 2 00EE Redcar and Cleveland UA V0728 2 3
12 E06000003 3 00EE Redcar and Cleveland UA V0728 2 3
13 E06000004 0 00EF Stockton-on-Tees UA H0738 40 4
14 E06000004 1 00EF Stockton-on-Tees UA H0738 14 4
15 E06000004 2 <NA> <NA> <NA> 0 4
具体来说,因素的水平改变了它们的格式,而且在某些情况下,观察结果被错误地重新编码(例如oslaua = E06000001
- 第 3 行)
我不明白为什么关卡会改变它们的格式以及我如何才能保持它们的原始(字母数字)格式。另外,为什么有些观察结果没有正确重新编码。
非常感谢任何解决这些问题的建议。
谢谢!
这应该适合你:
library(zoo)
df %>%
group_by(oslaua) %>%
mutate(old.la.1 = na.locf(old.la))
它用zoo
的最后一个结转函数来代替NA的。它是类型安全的。在您的代码中,ifelse
正在构建两个向量(一个用于测试解析为 TRUE
的情况,另一个用于解析为 FALSE
的情况。为了确保兼容性,似乎 ifelse
将其中的每一个都简化为最基本、最常见的类型。在因子的情况下,这是一个整数 (运行 typeof(df$old.la)
。
这是另一个使用 data.table
的选项
library(data.table)
setDT(df)[, old.la1 := levels(droplevels(old.la)), by = oslaua]
对于多列
nm1 <- c("old.la", "la", "dclg.code")
df1 <- setDT(df)[, lapply(.SD, function(x) levels(droplevels(x))[1]) ,
by = oslaua, .SDcols = nm1][df, on = "oslaua"]
df1[, !grepl("i\.", names(df1)), with = FALSE]
我们最初的想法是
setDT(df)[, (nm1) := lapply(.SD, function(x)
factor(levels(droplevels(x)))) , by = oslaua, .SDcols = nm1]
但出于某种原因,在每个组中转换为 factor
会得到一些奇怪的输出,输出中的每一列只有一个级别(使用 v1.10.0)
或者,避免创建新变量的更优雅的解决方案是使用 fill()
from tidyr
:
data = data %>% group_by(oslaua) %>% fill(old.la, la, dclg.code)
data
产生:
> data
Source: local data frame [15 x 6]
Groups: oslaua [4]
oslaua wave old.la la dclg.code novo_entries
<fctr> <fctr> <fctr> <fctr> <fctr> <int>
1 E06000001 0 00EB Hartlepool UA H0724 24
2 E06000001 1 00EB Hartlepool UA H0724 4
3 E06000001 2 00EB Hartlepool UA H0724 0
4 E06000001 3 00EB Hartlepool UA H0724 1
5 E06000002 0 00EC Middlesbrough UA W0734 35
6 E06000002 1 00EC Middlesbrough UA W0734 15
7 E06000002 2 00EC Middlesbrough UA W0734 1
8 E06000002 3 00EC Middlesbrough UA W0734 0
9 E06000003 0 00EE Redcar and Cleveland UA V0728 49
10 E06000003 1 00EE Redcar and Cleveland UA V0728 7
11 E06000003 2 00EE Redcar and Cleveland UA V0728 2
12 E06000003 3 00EE Redcar and Cleveland UA V0728 2
13 E06000004 0 00EF Stockton-on-Tees UA H0738 40
14 E06000004 1 00EF Stockton-on-Tees UA H0738 14
15 E06000004 2 00EF Stockton-on-Tees UA H0738 0
我有一个纵向结构的数据框如下:
df = structure(list(oslaua = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("E06000001", "E06000002",
"E06000003", "E06000004"), class = "factor"), wave = structure(c(1L,
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L), .Label = c("0",
"1", "2", "3"), class = "factor"), old.la = structure(c(1L, 1L,
NA, 1L, 2L, 2L, 2L, NA, 3L, 3L, 3L, 3L, 4L, 4L, NA), .Label = c("00EB",
"00EC", "00EE", "00EF"), class = "factor"), la = structure(c(1L,
1L, NA, 1L, 2L, 2L, 2L, NA, 3L, 3L, 3L, 3L, 4L, 4L, NA), .Label = c("Hartlepool UA",
"Middlesbrough UA", "Redcar and Cleveland UA", "Stockton-on-Tees UA"
), class = "factor"), dclg.code = structure(c(1L, 1L, NA, 1L,
4L, 4L, 4L, NA, 3L, 3L, 3L, 3L, 2L, 2L, NA), .Label = c("H0724",
"H0738", "V0728", "W0734"), class = "factor"), novo_entries = c(24L,
4L, 0L, 1L, 35L, 15L, 1L, 0L, 49L, 7L, 2L, 2L, 40L, 14L, 0L)), .Names = c("oslaua",
"wave", "old.la", "la", "dclg.code", "novo_entries"), row.names = c(NA,
15L), class = "data.frame")
我的标识符变量是 oslaua
,我的时间变量是 wave
。 old.la
、la
和 dclg.code
是具有 NA 的因子变量。我的
目标包括使用与每个标识符 (oslaua
) 关联的每个变量的级别重新编码我的 NA
。我尝试使用以下方法针对 old.la
的情况执行此操作:
df = df %>% group_by(oslaua) %>% mutate(old.la.1 = ifelse(is.na(old.la), unique(old.la), old.la)) %>% as.data.frame()
我部分明白了我的目的,但如您所见,存在一些问题:
> df
oslaua wave old.la la dclg.code novo_entries old.la.1
1 E06000001 0 00EB Hartlepool UA H0724 24 1
2 E06000001 1 00EB Hartlepool UA H0724 4 1
3 E06000001 2 <NA> <NA> <NA> 0 2
4 E06000001 3 00EB Hartlepool UA H0724 1 1
5 E06000002 0 00EC Middlesbrough UA W0734 35 2
6 E06000002 1 00EC Middlesbrough UA W0734 15 2
7 E06000002 2 00EC Middlesbrough UA W0734 1 2
8 E06000002 3 <NA> <NA> <NA> 0 2
9 E06000003 0 00EE Redcar and Cleveland UA V0728 49 3
10 E06000003 1 00EE Redcar and Cleveland UA V0728 7 3
11 E06000003 2 00EE Redcar and Cleveland UA V0728 2 3
12 E06000003 3 00EE Redcar and Cleveland UA V0728 2 3
13 E06000004 0 00EF Stockton-on-Tees UA H0738 40 4
14 E06000004 1 00EF Stockton-on-Tees UA H0738 14 4
15 E06000004 2 <NA> <NA> <NA> 0 4
具体来说,因素的水平改变了它们的格式,而且在某些情况下,观察结果被错误地重新编码(例如oslaua = E06000001
- 第 3 行)
我不明白为什么关卡会改变它们的格式以及我如何才能保持它们的原始(字母数字)格式。另外,为什么有些观察结果没有正确重新编码。
非常感谢任何解决这些问题的建议。
谢谢!
这应该适合你:
library(zoo)
df %>%
group_by(oslaua) %>%
mutate(old.la.1 = na.locf(old.la))
它用zoo
的最后一个结转函数来代替NA的。它是类型安全的。在您的代码中,ifelse
正在构建两个向量(一个用于测试解析为 TRUE
的情况,另一个用于解析为 FALSE
的情况。为了确保兼容性,似乎 ifelse
将其中的每一个都简化为最基本、最常见的类型。在因子的情况下,这是一个整数 (运行 typeof(df$old.la)
。
这是另一个使用 data.table
library(data.table)
setDT(df)[, old.la1 := levels(droplevels(old.la)), by = oslaua]
对于多列
nm1 <- c("old.la", "la", "dclg.code")
df1 <- setDT(df)[, lapply(.SD, function(x) levels(droplevels(x))[1]) ,
by = oslaua, .SDcols = nm1][df, on = "oslaua"]
df1[, !grepl("i\.", names(df1)), with = FALSE]
我们最初的想法是
setDT(df)[, (nm1) := lapply(.SD, function(x)
factor(levels(droplevels(x)))) , by = oslaua, .SDcols = nm1]
但出于某种原因,在每个组中转换为 factor
会得到一些奇怪的输出,输出中的每一列只有一个级别(使用 v1.10.0)
或者,避免创建新变量的更优雅的解决方案是使用 fill()
from tidyr
:
data = data %>% group_by(oslaua) %>% fill(old.la, la, dclg.code)
data
产生:
> data
Source: local data frame [15 x 6]
Groups: oslaua [4]
oslaua wave old.la la dclg.code novo_entries
<fctr> <fctr> <fctr> <fctr> <fctr> <int>
1 E06000001 0 00EB Hartlepool UA H0724 24
2 E06000001 1 00EB Hartlepool UA H0724 4
3 E06000001 2 00EB Hartlepool UA H0724 0
4 E06000001 3 00EB Hartlepool UA H0724 1
5 E06000002 0 00EC Middlesbrough UA W0734 35
6 E06000002 1 00EC Middlesbrough UA W0734 15
7 E06000002 2 00EC Middlesbrough UA W0734 1
8 E06000002 3 00EC Middlesbrough UA W0734 0
9 E06000003 0 00EE Redcar and Cleveland UA V0728 49
10 E06000003 1 00EE Redcar and Cleveland UA V0728 7
11 E06000003 2 00EE Redcar and Cleveland UA V0728 2
12 E06000003 3 00EE Redcar and Cleveland UA V0728 2
13 E06000004 0 00EF Stockton-on-Tees UA H0738 40
14 E06000004 1 00EF Stockton-on-Tees UA H0738 14
15 E06000004 2 00EF Stockton-on-Tees UA H0738 0