1

我有一个这样的数据框:

id <- c(1, 2, 3, 4, 5, 6, 7)
var1 <- c(1, NA, 2, NA, 1, 1, 2) 
var2 <- c(1, 1, 2, 2, NA, 2, 2)

但是,我如何设法创建一个新向量,该向量从 var2 中获取值,并将其替换为 var1 中的 NA,否则只要从 var1 中获取值(1 或 2),只要它有一个值?

我在想类似的事情:

id <- c(1, 2, 3, 4, 5, 6, 7)
var1 <- c(1, NA, 2, NA, 1, 1, 2) 
var2 <- c(1, 1, 2, 2, NA, 2, 2)
newvar <- c(1, 1, 2, 2, 1, 1, 2)

另一个数据帧也是如此,其中有更多向量:

id   <- c(1, 2, 3, 4, 5, 6, 7)
var1 <- c(1, NA,2, NA,NA,1, 2) 
var2 <- c(1, 1, 2, 2, NA,2, 2)
var3 <- c(2, 1, 2, 1, 1, 1, 2)
var4 <- c(1, 1, 2, NA,2, 1, 2)

在这种情况下,我想创建另一个向量“newvar”,它从 var2、var3 和 var4 中获取主导值,并将其替换为 var1 中的 NA。

因此,起点始终是 var1 中的内容。但是对于 id4 和 id5 fx,其他变量中没有显性值 - 然后我想用第一个变量中的值替换 NA,在这两种情况下,分别来自 var 2 和 var3 的值。

id   <- c(1, 2, 3, 4, 5, 6, 7)
var1 <- c(1, NA,2, NA,NA,1, 2) 
var2 <- c(1, 1, 2, 2, NA,2, 2)
var3 <- c(2, 1, 2, 1, 1, 1, 2)
var4 <- c(1, 1, 2, NA,2, 1, 2)
newvar <- c(1, 1, 2, 2, 1, 1, 2)

如何以简单的方式做到这一点?

谢谢!

4

5 回答 5

4

它可以用来覆盖下一个向量[<-的值。ReduceNA

var1 <- c(1, NA, 2, NA, 1, 1, 2) 
var2 <- c(1, 1, 2, 2, NA, 2, 2)
#`[<-`(var1, is.na(var1), var2[is.na(var1)]) #In case of only two vectors
Reduce(function(a, b) `[<-`(a, is.na(a), b[is.na(a)]), list(var1, var2))
#[1] 1 1 2 2 1 1 2

var1 <- c(1, NA,2, NA,NA,1, 2) 
var2 <- c(1, 1, 2, 2, NA,2, 2)
var3 <- c(2, 1, 2, 1, 1, 1, 2)
var4 <- c(1, 1, 2, NA,2, 1, 2)
Reduce(function(a, b) `[<-`(a, is.na(a), b[is.na(a)]), list(var1, var2, var3, var4))
#[1] 1 1 2 2 1 1 2

不知何故喜欢做什么:

var1 <- c(1, NA, 2, NA, 1, 1, 2) 
var2 <- c(1, 1, 2, 2, NA, 2, 2)
newvar <- var1
i <- is.na(newvar)
newvar[i] <- var2[i]
newvar
#[1] 1 1 2 2 1 1 2
于 2021-07-20T08:39:01.560 回答
3

尝试这个。

df  %>% 
  mutate(newavar = coalesce(var1,var2, var3, var4))
于 2021-07-20T09:07:57.377 回答
2

您可以使用coalesce来自dplyr.

library(dplyr)
df$newvar <- do.call(coalesce, select(df, starts_with('var')))
df

#  id var1 var2 var3 var4 newvar
#1  1    1    1    2    1      1
#2  2   NA    1    1    1      1
#3  3    2    2    2    2      2
#4  4   NA    2    1   NA      2
#5  5   NA   NA    1    2      1
#6  6    1    2    1    1      1
#7  7    2    2    2    2      2

数据

id   <- c(1, 2, 3, 4, 5, 6, 7)
var1 <- c(1, NA,2, NA,NA,1, 2) 
var2 <- c(1, 1, 2, 2, NA,2, 2)
var3 <- c(2, 1, 2, 1, 1, 1, 2)
var4 <- c(1, 1, 2, NA,2, 1, 2)
df <- data.frame(id, var1, var2, var3, var4)
于 2021-07-20T08:34:11.957 回答
1

With tidyverse,我们可以使用invokewithcoalesce

library(dplyr)
library(purrr)
df %>% 
   mutate(newvar = invoke(coalesce, select(cur_data(), starts_with('var'))))
  id var1 var2 var3 var4 newvar
1  1    1    1    2    1      1
2  2   NA    1    1    1      1
3  3    2    2    2    2      2
4  4   NA    2    1   NA      2
5  5   NA   NA    1    2      1
6  6    1    2    1    1      1
7  7    2    2    2    2      2

数据

df <- structure(list(id = c(1, 2, 3, 4, 5, 6, 7), var1 = c(1, NA, 2, 
NA, NA, 1, 2), var2 = c(1, 1, 2, 2, NA, 2, 2), var3 = c(2, 1, 
2, 1, 1, 1, 2), var4 = c(1, 1, 2, NA, 2, 1, 2)),
 class = "data.frame", row.names = c(NA, 
-7L))
于 2021-07-20T18:42:07.727 回答
1

使用pmin+的基本 R 选项col

df$newvar <- df[-1][
    cbind(
        1:nrow(df),
        do.call(
            pmin,
            data.frame(
                replace(
                    u <- (!is.na(df[-1])) * col(df[-1]),
                    u == 0, Inf
                )
            )
        )
    )
]

> df
  id var1 var2 var3 var4 newvar
1  1    1    1    2    1      1
2  2   NA    1    1    1      1
3  3    2    2    2    2      2
4  4   NA    2    1   NA      2
5  5   NA   NA    1    2      1
6  6    1    2    1    1      1
7  7    2    2    2    2      2
于 2021-07-20T18:59:19.443 回答