我有一个数据框,其中包含丢失的数据(NA)。我想找到只有一个非缺失值的列,然后用该值填充这些列。例如,如果我的原始数据集是这样的:
df = data.frame(A=c(1,2,NA,NA,1), B=c(NA,NA,3,3,3), C=c(2,5,6,3,6), D = c(NA,1, NA,1,1))
A B C D
1 1 NA 2 NA
2 2 NA 5 1
3 NA 3 6 NA
4 NA 3 3 1
5 1 3 6 1
我想实现:
A B C D
1 1 3 2 1
2 2 3 5 1
3 NA 3 6 1
4 NA 3 3 1
5 1 3 6 1
我首先创建此函数是为了执行我想要的操作:(请告诉我您是否对此有更好的选择)
fill_NAs <- function(x){
x %>% fill(., .direction = "up") %>%
fill(., .direction = "down")
}
然后我尝试使用mutate_at或mutate_if函数,但是我无法使其正常工作。我的一些尝试如下:
1)
df= df %>% mutate_if ( ~ length(unique(na.omit(.)))==1, ~ fill_NAs(.))
我收到此错误:
mutate_impl(.data,点)中的错误:评估错误:不适用 “ fill_”方法应用于类“ c('double', '数字')“
。
2)
df_PMM_imp = df_PMM_imp %>% mutate_at(.,names(select_if(.,length(unique(na.omit(.)))==1)), ~ fill_NAs(.))
我收到此错误:
tbl_if_vars(.tbl,.predicate,caller_env(), .include_group_vars = TRUE):length(.p)== length(tibble_vars)为 不正确
通常来说,我似乎无法理解mutate_if或mutate_at的逻辑,我总是遇到这样的问题。所以我的问题是:
1)什么是实现我想要的正确语法? 2)为什么我在上面得到这些错误,我在做什么错了?
非常感谢。
答案 0 :(得分:1)
您可以遍历各列,检查不是NA
的唯一元素的长度,如果列中仅包含一个唯一元素,则替换列中的NA
。
df[] <- lapply(df, function(x) {
y <- unique(na.omit(x))
if(length(y) == 1) {
x <- y
} else x
})
结果
df
A B C D
1 1 3 2 1
2 2 3 5 1
3 NA 3 6 1
4 NA 3 3 1
5 1 3 6 1
答案 1 :(得分:0)
你好,@ Elif CansuAkoğuz,
通过使用for()
循环遍历数据框并检查每一列是否满足要求,您可以相当轻松地实现目标:
for (i in 1:ncol(df)) {
if (any(is.na(unique(df[i]))) == TRUE & nrow(unique(df[i])) == 2) {
...
}
}
使用语句any(is.na(unique(df[i])))
,您可以检查列中是否有NA
;使用nrow(unique(df[i])) == 2
,您可以检查列中是否仅包含两个唯一值。因此,如果一列同时满足这两个语句,您就会知道它由2个值组成,其中一个在NA
中。
接下来,您要用非NA
的值替换列中的所有值。为此,您可以使用na.omit()
抛出NA
值,然后重复剩余的值,无论数据帧有多长。
一个问题是,它将返回列表格式,因此您必须使用unlist()
函数来解决此问题。
整个循环最终看起来像这样:
for (i in 1:ncol(df)) {
if (any(is.na(unique(df[i]))) == TRUE & nrow(unique(df[i])) == 2) {
df[i] <- unlist(rep(na.omit(unique(df[i])), nrow(df)))
}
}
祝你好运!
答案 2 :(得分:0)
一种dplyr
方式:
library(dplyr)
df %>%
mutate_all(~ case_when(
n_distinct(.[na.omit(.)]) == 1 ~ first(na.omit(.)),
TRUE ~ .
)
)
输出:
A B C D
1 1 3 2 1
2 2 3 5 1
3 NA 3 6 1
4 NA 3 3 1
5 1 3 6 1