根据 id 将 NA 替换为其他行值
Replace NA with other row value based on id
我想用基于 ID 的其他行的值替换 NA。
我发现了类似的问题,但我没有找到解决问题的方法。
table以下部分
XCODE Age Sex ResultA ResultB ResultC
1 X001 12 2 2 3 4
2 X002 23 2 4 6 66
3 X003 NA NA NA NA NA
4 X004 32 1 1 7 3
5 X005 NA NA NA NA NA
6 X001 NA NA NA NA NA
7 X002 NA NA NA NA NA
8 X003 33 1 8 7 6
9 X004 NA NA NA NA NA
10 X005 55 2 8 8 8
我有超过 6000 列的 SPSS 文件。
我用过
library(data.table)
setDT(dataset)[, Age:= Age[!is.na(Age)][1L] , by = XCODE]
但这只适用于单列,我需要处理很多列。
那么如何在所有列上执行上面的代码?
使用 data.table
我们可以 select 我们想要的列 replace
library(data.table)
setDT(df)[, (2:ncol(df)) := lapply(.SD, function(x)
replace(x, is.na(x), x[!is.na(x)][1])) , XCODE]
df
# XCODE Age Sex ResultA ResultB ResultC
# 1: X001 12 2 2 3 4
# 2: X002 23 2 4 6 66
# 3: X003 33 1 8 7 6
# 4: X004 32 1 1 7 3
# 5: X005 55 2 8 8 8
# 6: X001 12 2 2 3 4
# 7: X002 23 2 4 6 66
# 8: X003 33 1 8 7 6
# 9: X004 32 1 1 7 3
#10: X005 55 2 8 8 8
使用 dplyr
中的相同逻辑,我们可以将 NA
s 替换为所有列的组的第一个非 NA 值
library(dplyr)
df %>%
group_by(XCODE) %>%
mutate_all(~replace(., is.na(.), .[!is.na(.)][1]))
# XCODE Age Sex ResultA ResultB ResultC
# <fct> <int> <int> <int> <int> <int>
# 1 X001 12 2 2 3 4
# 2 X002 23 2 4 6 66
# 3 X003 33 1 8 7 6
# 4 X004 32 1 1 7 3
# 5 X005 55 2 8 8 8
# 6 X001 12 2 2 3 4
# 7 X002 23 2 4 6 66
# 8 X003 33 1 8 7 6
# 9 X004 32 1 1 7 3
#10 X005 55 2 8 8 8
或仅select列
cols <- c("Age", "Sex", "ResultA","ResultB")
df %>%
group_by(XCODE) %>%
mutate_at(vars(cols), ~ replace(., is.na(.), .[!is.na(.)][1]))
我们可以按 XCODE
分组,并使用 fill()
将 NA 填入最新的非 NA。在这种情况下,我们需要填写两个方向。另请注意,由于您要填充所有变量,因此可以使用函数 everything()
library(tidyverse)
df %>%
group_by(XCODE) %>%
fill(everything()) %>%
fill(everything(), .direction = 'up')
这给出了,
# A tibble: 10 x 6
# Groups: XCODE [5]
XCODE Age Sex ResultA ResultB ResultC
<fct> <int> <int> <int> <int> <int>
1 X001 12 2 2 3 4
2 X001 12 2 2 3 4
3 X002 23 2 4 6 66
4 X002 23 2 4 6 66
5 X003 33 1 8 7 6
6 X003 33 1 8 7 6
7 X004 32 1 1 7 3
8 X004 32 1 1 7 3
9 X005 55 2 8 8 8
10 X005 55 2 8 8 8
我想用基于 ID 的其他行的值替换 NA。 我发现了类似的问题,但我没有找到解决问题的方法。
table以下部分
XCODE Age Sex ResultA ResultB ResultC
1 X001 12 2 2 3 4
2 X002 23 2 4 6 66
3 X003 NA NA NA NA NA
4 X004 32 1 1 7 3
5 X005 NA NA NA NA NA
6 X001 NA NA NA NA NA
7 X002 NA NA NA NA NA
8 X003 33 1 8 7 6
9 X004 NA NA NA NA NA
10 X005 55 2 8 8 8
我有超过 6000 列的 SPSS 文件。
我用过
library(data.table)
setDT(dataset)[, Age:= Age[!is.na(Age)][1L] , by = XCODE]
但这只适用于单列,我需要处理很多列。
那么如何在所有列上执行上面的代码?
使用 data.table
我们可以 select 我们想要的列 replace
library(data.table)
setDT(df)[, (2:ncol(df)) := lapply(.SD, function(x)
replace(x, is.na(x), x[!is.na(x)][1])) , XCODE]
df
# XCODE Age Sex ResultA ResultB ResultC
# 1: X001 12 2 2 3 4
# 2: X002 23 2 4 6 66
# 3: X003 33 1 8 7 6
# 4: X004 32 1 1 7 3
# 5: X005 55 2 8 8 8
# 6: X001 12 2 2 3 4
# 7: X002 23 2 4 6 66
# 8: X003 33 1 8 7 6
# 9: X004 32 1 1 7 3
#10: X005 55 2 8 8 8
使用 dplyr
中的相同逻辑,我们可以将 NA
s 替换为所有列的组的第一个非 NA 值
library(dplyr)
df %>%
group_by(XCODE) %>%
mutate_all(~replace(., is.na(.), .[!is.na(.)][1]))
# XCODE Age Sex ResultA ResultB ResultC
# <fct> <int> <int> <int> <int> <int>
# 1 X001 12 2 2 3 4
# 2 X002 23 2 4 6 66
# 3 X003 33 1 8 7 6
# 4 X004 32 1 1 7 3
# 5 X005 55 2 8 8 8
# 6 X001 12 2 2 3 4
# 7 X002 23 2 4 6 66
# 8 X003 33 1 8 7 6
# 9 X004 32 1 1 7 3
#10 X005 55 2 8 8 8
或仅select列
cols <- c("Age", "Sex", "ResultA","ResultB")
df %>%
group_by(XCODE) %>%
mutate_at(vars(cols), ~ replace(., is.na(.), .[!is.na(.)][1]))
我们可以按 XCODE
分组,并使用 fill()
将 NA 填入最新的非 NA。在这种情况下,我们需要填写两个方向。另请注意,由于您要填充所有变量,因此可以使用函数 everything()
library(tidyverse)
df %>%
group_by(XCODE) %>%
fill(everything()) %>%
fill(everything(), .direction = 'up')
这给出了,
# A tibble: 10 x 6 # Groups: XCODE [5] XCODE Age Sex ResultA ResultB ResultC <fct> <int> <int> <int> <int> <int> 1 X001 12 2 2 3 4 2 X001 12 2 2 3 4 3 X002 23 2 4 6 66 4 X002 23 2 4 6 66 5 X003 33 1 8 7 6 6 X003 33 1 8 7 6 7 X004 32 1 1 7 3 8 X004 32 1 1 7 3 9 X005 55 2 8 8 8 10 X005 55 2 8 8 8