根据ID将NA替换为其他行值

时间:2019-04-02 09:56:35

标签: r spss

我想根据ID用其他行中的值替换NA。 我发现了类似的问题,但没有找到解决问题的方法。

表格下方

   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]

但这仅适用于单列,我需要处理许多列。

那么如何在所有列上执行上面的代码?

2 个答案:

答案 0 :(得分:0)

使用data.table,我们可以选择要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替换为所有列的组的第一个非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

或仅选定列

cols <- c("Age", "Sex", "ResultA","ResultB")
df %>%
  group_by(XCODE) %>%
  mutate_at(vars(cols), ~ replace(., is.na(.), .[!is.na(.)][1]))

答案 1 :(得分:0)

我们可以按from pyspark.sql import SparkSession spark = SparkSession.builder.appName('app_name').getOrCreate() your_pyspark_df = spark.createDataFrame(your_pd_df) 分组并使用XCODE用最新的非NA填充NA。在这种情况下,我们需要同时填写两个方向。另外请注意,由于您要填充所有变量,因此可以使用函数fill()

everything()

给出,

library(tidyverse)

df %>% 
 group_by(XCODE) %>% 
 fill(everything()) %>% 
 fill(everything(), .direction = 'up')