如何在不删除列或行的情况下从数据集中清除或删除 NA 值

How to clean or remove NA values from a dataset without remove the column or row

是否有任何优雅的解决方案可以从 NA 值中清除数据帧而不删除 NA 所在的行或列?

示例:

输入数据帧

    C1    C2     C3
 R1  A   <NA>  <NA>
 R2 <NA>  A    <NA>
 R3 <NA> <NA>   A
 R4  B   <NA>  <NA>
 R5 <NA>  B    <NA>
 R6 <NA> <NA>  <NA>
 R7  C   <NA>   B
 R8       C    <NA>
 R9            <NA>
 R10           <NA>
 R11            C

输出数据帧

    C1  C2  C3
R1  A   A   A
R2  B   B   B
R3  C   C   C

例如,这是一个充满 NA 值的混乱数据框 (df1)

    A       B       C       D       E       F    G    H    I    J    K
1 Healthy    <NA>    <NA>    <NA>    <NA>    <NA> <NA> <NA> <NA> <NA> <NA>
2    <NA> Healthy    <NA>    <NA>    <NA>    <NA> <NA> <NA> <NA> <NA> <NA>
3    <NA>    <NA> Healthy    <NA>    <NA>    <NA> <NA> <NA> <NA> <NA> <NA>
4    <NA>    <NA>    <NA> Healthy    <NA>    <NA> <NA> <NA> <NA> <NA> <NA>
5    <NA>    <NA>    <NA>    <NA> Healthy    <NA> <NA> <NA> <NA> <NA> <NA>
6    <NA>    <NA>    <NA>    <NA>    <NA> Healthy <NA> <NA> <NA> <NA> <NA>

数据框应该是这样的。

   X1        X2        X3      X4        X5        X6        X7      X8      X9       X10       X11
1 Healthy   Healthy   Healthy Healthy   Healthy   Healthy   Healthy Healthy Healthy   Healthy   Healthy
2 Healthy   Healthy   Healthy Healthy   Healthy   Healthy   Healthy Healthy Healthy   Healthy   Healthy
3 Healthy ICDAS_1_2 ICDAS_1_2 Healthy ICDAS_1_2 ICDAS_1_2 ICDAS_1_2 Healthy Healthy ICDAS_1_2 ICDAS_1_2
4 Healthy   Healthy   Healthy Healthy   Healthy   Healthy   Healthy Healthy Healthy   Healthy   Healthy
5 Healthy   Healthy   Healthy Healthy   Healthy   Healthy   Healthy Healthy Healthy   Healthy   Healthy
6 Healthy   Healthy   Healthy Healthy   Healthy   Healthy   Healthy Healthy Healthy   Healthy   Healthy

请注意,原始数据帧中的单元格 B-2 现在位于 X2-1 中。所以这里的主要问题是从 Calc 或 Excel

中找到等价于 "delete the cell and move all the cells up" 的函数

我找到的所有答案都删除了 值所在的所有行或列。 我设法做到这一点的方法是(抱歉,如果这是原始的)是仅将有效值提取到新数据帧:

首先。我创建一个空数据框

library("data.table") # required package
new_dataframe <-  data.frame(matrix("", ncol = 11, nrow = 1400) )

然后,我将每个有效值从旧数据帧复制到新数据帧

new_dataframe$X1 <- df1$A[!is.na(df2$A)]
new_dataframe$X2 <- df1$B[!is.na(df2$B)]
new_dataframe$X3 <- df1$C[!is.na(df2$C)]

等等

所以,我的问题是:对于 "clean" 来自 NA 值的数据帧是否有更优雅的解决方案?

非常感谢任何帮助。

如果这对您手动有效:

new_dataframe$X1 <- df1$A[!is.na(df2$A)]
new_dataframe$X2 <- df1$B[!is.na(df2$B)]
new_dataframe$X3 <- df1$C[!is.na(df2$C)]

那么这应该会自动运行:

new_dataframe = as.data.frame(lapply(df1, na.omit))

也应该可以工作(在任意数量的列上)。 (你的代码更直接的翻译是皮埃尔在评论中建议的:as.data.frame(lapply(mydf, function(x) x[!is.na(x)]))。)

注意数据框必须是矩形的(每列的行数必须相同),所以这会像你一样工作可能希望并期望 只有每列具有相同数量的 non-missing 个值。如果某些行的non-missing值较少,它们将被回收以填充数据框的长度:

x = data.frame(a = c(1, NA, 2), b = c(2, NA, 3), c = c(NA, "A", NA))
x
#    a  b    c
# 1  1  2 <NA>
# 2 NA NA    A
# 3  2  3 <NA>

as.data.frame(lapply(x, na.omit))
#   a b c
# 1 1 2 A
# 2 2 3 A

更好的方法可能是先转换为列表:

y = lapply(x, na.omit)

然后您可以在决定是否要强制转换为数据框之前查看您得到的内容sapply(y, length)