ste*_*--g 5 r na dplyr tidyverse
这个问题很难用标题行来表达,但它与通常的“如何根据另一列中的值更改一列中的值”不同。有两个问题我在其他地方没有看到处理过:1)我正在处理 NA,而不是值,2)我正在处理涉及多个列之间 OR 关系的条件,即 if is V01
NA或 V02
is NA ,然后使foo
该行的 var(已存在但没有 NA)为 NA。
这是一个小问题来说明:
tbl <- tibble(
V01 = 10:15,
V02 = 1:6,
V03 = V02 * 2,
foo = V03 * 2
)
# sprinkle around some NAs
tbl[1,2] = NA
tbl[4,1] = NA
tbl[4,2] = NA
tbl[6,1:3] = NA
Run Code Online (Sandbox Code Playgroud)
产生这个表:
# A tibble: 6 x 4
V01 V02 V03 foo
<int> <int> <dbl> <dbl>
1 10 NA 2 4
2 11 2 4 8
3 12 3 6 12
4 NA NA 8 16
5 14 5 10 20
6 NA NA NA 24
Run Code Online (Sandbox Code Playgroud)
最终我想为中的每一行生成这种逻辑tbl
:
if (V01 == NA | V02 == NA | V03 == NA) {foo = NA}
Run Code Online (Sandbox Code Playgroud)
我首先尝试根据一列mutate
更改foo
为 NA,如下所示:
tbl <- tbl %>%
mutate(
foo = case_when(V01 == NA ~ NA)
)
Run Code Online (Sandbox Code Playgroud)
但即使在这个简单的情况下,mutate 也将 的每个值更改foo
为 NA:
# A tibble: 6 x 4
V01 V02 V03 foo
<int> <int> <dbl> <lgl>
1 10 NA 2 NA
2 11 2 4 NA
3 12 3 6 NA
4 NA NA 8 NA
5 14 5 10 NA
6 NA NA NA NA
Run Code Online (Sandbox Code Playgroud)
我想也许我需要rowwise
在那里,但这并没有改变结果。
然后我想也许是因为 NA 很奇怪,所以让我们尝试一些更简单的方法:如果是 NA则更改为foo
-1 :V01
tbl <- tbl %>%
mutate(
foo = case_when(V01 == NA ~ -1)
)
Run Code Online (Sandbox Code Playgroud)
但这产生了相同的结果,所有 的值都foo
更改为 NA(并且第 4 行中的值foo
也没有更改为 -1)。
然后我决定做一些更简单的事情。将 NA 排除在外。如果V01
为 10(仅在第一行中),则foo
将该行中的值更改为 -1。所以:
tbl <- tbl %>%
mutate(
foo = case_when(V01 == 10 ~ -1)
)
Run Code Online (Sandbox Code Playgroud)
这就产生了这个:
# A tibble: 6 x 4
V01 V02 V03 foo
<int> <int> <dbl> <dbl>
1 10 NA 2 -1
2 11 2 4 NA
3 12 3 6 NA
4 NA NA 8 NA
5 14 5 10 NA
6 NA NA NA NA
Run Code Online (Sandbox Code Playgroud)
那么为什么要mutate
更改不满足语句中指定条件的行中的值呢mutate
?
请注意,我什至还没有达到 OR 条件。就其价值而言,这就是我想要得到的结果:
# A tibble: 6 x 4
V01 V02 V03 foo
<int> <int> <dbl> <dbl>
1 10 NA 2 NA
2 11 2 4 8
3 12 3 6 12
4 NA NA 8 NA
5 14 5 10 20
6 NA NA NA NA
Run Code Online (Sandbox Code Playgroud)
我无法使用 dplyrna_if
函数,因为它只需要一个值来替换为 NA,而不是一个条件。
任何指导将不胜感激。谢谢!
这里有几个选项 -
rowSums
-library(dplyr)
tbl %>%
mutate(foo = replace(foo, rowSums(is.na(select(., starts_with('V')))) > 0, NA))
# V01 V02 V03 foo
# <int> <int> <dbl> <dbl>
#1 10 NA 2 NA
#2 11 2 4 8
#3 12 3 6 12
#4 NA NA 8 NA
#5 14 5 10 20
#6 NA NA NA NA
Run Code Online (Sandbox Code Playgroud)
rowwise
-tbl %>%
rowwise() %>%
mutate(foo = if(any(is.na(c_across(starts_with('V'))))) NA else foo)
Run Code Online (Sandbox Code Playgroud)
如果任何以 开头的列中有值,则这两个值都会替换foo
为。NA
NA
V
就这段代码而言
tbl <- tbl %>%
mutate(foo = case_when(V01 == 10 ~ -1))
Run Code Online (Sandbox Code Playgroud)
case_when
NA
如果不满足条件则默认返回。要获得相同的价值,你可以这样做
tbl %>%
mutate(foo = case_when(V01 == 10 ~ -1,
TRUE ~ foo))
Run Code Online (Sandbox Code Playgroud)