用两列除法代替NAs

时间:2017-05-25 21:23:59

标签: r dataframe

我有一个看起来像这样的data.frame:

a   b  c   d
1   2  NA  1
NA  2  2   1 
3   2  NA  1
NA  NA 20  2

我想用c / d(并删除cd)替换NAs,如下所示:

a  b
1  2
2  2
3  2
10 10

某些背景:d是该特定行中NA的总和。

我不知道列的名称,所以我尝试了一些变体:

df2[, 1:(length(colnames(df2)) - 2)][is.na(df2[, 1:(length(colnames(df2)) - 2)])] = df2$c / df2$d

但得到了:

Error in `[<-.data.frame`(`*tmp*`, is.na(df2[, 1:(length(colnames(df2)) -  : 
  'value' is the wrong length

2 个答案:

答案 0 :(得分:1)

您可以使用dplyr来完成此操作。


library(dplyr)

df <- tibble(
  a = c(1, NA, 3, NA),
  b = c(2, 2, 2, NA),
  c = c(NA, 2, NA, 20L),
  d = c(1, 1, 1, 2)
)

df %>% 
  mutate_at(vars(-c, -d), funs(if_else(is.na(.), c / d, .))) %>% 
  select(-c, -d)

#> # A tibble: 4 x 2
#>       a     b
#>   <dbl> <dbl>
#> 1     1     2
#> 2     2     2
#> 3     3     2
#> 4    10    10

您可以使用vars()中的任何功能在?dplyr::select_helpers来电中指定变量。这些可以是正则表达式,一个简单的名称向量,或者您可以使用除cd之外的所有列(因为我已将此示例更改为现在)。

答案 1 :(得分:0)

library(data.table)
data<-fread("a   b  c   d
1   2  NA  1
            NA  2  2   1 
            3   2  NA  1
            NA  NA 20  2")
names_to_loop<-names(data)
names_to_loop<-names_to_loop[names_to_loop!="c"&names_to_loop!="d"]
for (ntl in names_to_loop){
  set(data,j=ntl,value=ifelse(is.na(data[[ntl]]),data[["c"]]/data[["d"]],data[[ntl]]))
}
data[,c:=NULL]
data[,d:=NULL]
> data
    a  b
1:  1  2
2:  2  2
3:  3  2
4: 10 10