如何在数据框的行中替换非全部为 NA 的行中的 NA?

4

我有一个数据框看起来像这样:

df <- data.frame(matrix(c(1,351,NA,1,0,2,585,0,1,1,3,321,NA,0,1,4,964,NA,NA,NA,5,556,0,1,NA), ncol = 5, byrow = TRUE))
colnames(df) <- c('id','value','v1','v2','v3')

现在我想把子集c('v1','v2','v3')中所有不是所有NA的行中的NA替换为0(零)。
所以我想要这样:
R> df
  id value v1 v2 v3
1  1   351 NA  1  0
2  2   585  0  1  1
3  3   321 NA  0  1
4  4   964 NA NA NA
5  5   556  0  1 NA

最终变成这样:
R> df
  id value v1 v2 v3
1  1   351  0  1  0
2  2   585  0  1  1
3  3   321  0  0  1
4  4   964 NA NA NA
5  5   556  0  1  0

请注意,df[4, ]c('v1', 'v2', 'v3') 这些列仍然有NA值。
5个回答

2
在基本的R语言中,以下是一种方法:

最初的回答

#columns to check for NA
cols <- c("v1", "v2", "v3")
#rows which needs to be replaced
rows <- which(rowSums(is.na(df[cols])) != length(cols))
#Replace values which are NA to 0
df[rows, cols] <- replace(df[rows, cols], is.na(df[rows, cols]), 0)
df
#  id value v1 v2 v3
#1  1   351  0  1  0
#2  2   585  0  1  1
#3  3   321  0  0  1
#4  4   964 NA NA NA
#5  5   556  0  1  0

2

这里有一个使用传统循环的解决方案:

最初的回答:

for (r in 1:nrow(df))
{
  # check that not the all row is na but that there are some na
  if(!all(is.na(df[r,3:5])) && sum(is.na(df[r,3:5]>0)))
  {
    df[r,which(is.na(df[r,3:5]))+2]=0
  }  
}

1
使用`dplyr`,您可以尝试以下操作:

cols <- c("v1", "v2", "v3")

df %>%
 mutate(row_na = rowSums(is.na(select(., one_of(cols)))) == length(cols)) %>%
 mutate_at(vars(one_of(cols)), ~ ifelse(!row_na, replace(., is.na(.), 0), .)) %>%
 select(-row_na)

  id value v1 v2 v3
1  1   351  0  1  0
2  2   585  0  1  1
3  3   321  0  0  1
4  4   964 NA NA NA
5  5   556  0  1  0

1
一个简单的 dplyr 解决方案:
library(tidyverse)

df %>% 
  mutate_at(vars(v1:v3), ~ifelse(is.na(v1) & is.na(v2) & is.na(v3), NA, replace_na(., 0)))

它是如何用零替换NAs的? - tmfmnk
糟糕,打错了。已经编辑过了! - Shinobi_Atobe

0

尽可能简单:

df[ !(is.na(df$v1) & is.na(df$v2) & is.na(df$v3)) & is.na(df) ] <- 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接