处理非完整案件和影响?

时间:2018-05-01 13:58:43

标签: r dataframe

我有一个这样的数据框:

df <- data_frame('col1' = c(NA, 1, 2), 'col2' = c(34, NA, 44), 'indicator' = c(1,1,0))

我使用complete.cases标记了所有不完整的案例。

现在我要做的是用10替换NA值,如果indicator == 1,则替换0

尝试使用applyMARGIN = 2

执行此操作

请告知如何执行此类任务。

3 个答案:

答案 0 :(得分:3)

我们可以使用mutate_at中的dplyr。在vars内的mutate_at funs参数中指定感兴趣的列,创建一个case_when的逻辑条件,以替换满足条件的值

library(dplyr)
df %>%
  mutate_at(vars(matches("col\\d+")), 
       funs(case_when(is.na(.) & as.logical(indicator)~ 10, 
                      is.na(.) & !indicator ~ 0,  
                      TRUE ~ .)))
# A tibble: 3 x 3
#   col1  col2 indicator
#    <dbl> <dbl>     <dbl>
# 1    10    34         1
# 2     1    10         1 
# 3     2    44         0

这也可以使用data.table

完成
library(data.table)
setDT(df)
for(j in names(df)[1:2]) {
  i1 <- is.na(df[[j]]) 
  i2 <-  as.logical(df[['indicator']])

  set(df, i = which(i1 & i2), j = j, value = 10)
  set(df, i = which(i1 & !i2), j = j, value = 0)
 }

如果我们希望列的最大值而不是10来替换“指标”为1的NA值,请使用max

df %>%
  mutate_at(vars(matches("col\\d+")), 
       funs(case_when(is.na(.) & as.logical(indicator)~ max(., na.rm = TRUE), 
                      is.na(.) & !indicator ~ 0,  
                      TRUE ~ .)))
# A tibble: 3 x 3
#  col1  col2 indicator
#  <dbl> <dbl>     <dbl>
#1     2    34         1
#2     1    44         1
#3     2    44         0

答案 1 :(得分:2)

虽然您已经得到答案,但您可以按照问题中的要求使用apply

df <- data.frame('col1' = c(NA, 1, 2), 
                 'col2' = c(34, NA, 44), 
                 'indicator' = c(1,1,0), 
                 stringsAsFactors = F)

# columns in question
cols <- colnames(df)[!colnames(df) %in% c('indicator')]

# apply it row-wise
# using a nested ifelse call
df[cols] <- apply(df[cols], 2, function(x) {
  y <- ifelse(is.na(x),
              ifelse(df$indicator == 1, 10, 0),
              x)
  y
})
df

或者用较少的空格:

df[cols] <- apply(df[cols], 2, function(x) {
  (y <- ifelse(is.na(x), ifelse(df$indicator == 1, 10, 0), x))
})

这会产生

  col1 col2 indicator
1   10   34         1
2    1   10         1
3    2   44         0

答案 2 :(得分:1)

简单明了:

df$col1[ is.na(df$col1) ] <- ifelse(df$indicator == 1, 10, 0)
df$col2[ is.na(df$col2) ] <- ifelse(df$indicator == 1, 10, 0)

如果你有很多列,只需使用for循环:

for (col in c("col1", "col2")) { 
  df[ is.na(df[[col]]), col] <- ifelse(df$indicator == 1, 10, 0)
}