创建一个新变量,仅当 R 中满足条件时才打印一系列列中的第一个值
Create a new variable that prints the first value in a series of column only if the condition is met in R
我正在尝试创建一个新变量,它仅在满足特定条件时打印一系列列的第一个值。
澄清一下,我的数据库看起来像这样:
var1
var2
var3
var4
C7931
C3490
R0781
I10
R079
R0600
I10
C3490
S270XXA
S225XXA
C3490
C7931
我想创建一个变量 (main),仅当值不是以 C00 到 C99 开头时才在第一个 var 列中打印该值。如果该值确实以该条件开头,那么我想测试下一列的条件,直到满足条件,然后打印该值。
因此,对于上面的 table,新创建的变量 (main) 应该看起来像这样:
var1
var2
var3
var4
main
C7931
C3490
R0781
I10
R0781
R079
R0600
I10
C3490
R079
C0258
S225XXA
C3490
C7931
S225XXA
我不太确定从哪里开始,但我怀疑这可能涉及 mutate() 和 ifelse()
我们可以使用 grepl
通过遍历每一行来创建一个子集逻辑向量。匹配的模式是 C
后跟一个或多个数字 (\d+
) 并取反 (!
) 逻辑向量以对元素进行子集化,return 第一个 ([1]
)
df1$main <- apply(df1[startsWith(names(df1), "var")], 1,
function(x) x[!grepl("^C\d+", x)][1])
与 tidyverse
一起使用,可以将 rowwise
与 str_subset
一起使用
library(dplyr)
library(stringr)
df1 %>%
rowwise %>%
mutate(main = first(str_subset(c_across(starts_with("var")),
regex("^C\d+"), negate = TRUE))) %>%
ungroup
# A tibble: 3 × 5
var1 var2 var3 var4 main
<chr> <chr> <chr> <chr> <chr>
1 C7931 C3490 R0781 I10 R0781
2 R079 R0600 I10 C3490 R079
3 S270XXA S225XXA C3490 C7931 S270XXA
数据
df1 <- structure(list(var1 = c("C7931", "R079", "S270XXA"), var2 = c("C3490",
"R0600", "S225XXA"), var3 = c("R0781", "I10", "C3490"), var4 = c("I10",
"C3490", "C7931")), class = "data.frame", row.names = c(NA, -3L
))
这将创建一个列,其中存储所有不满足条件的值:
来自 akrun 的数据:
library(tidyverse)
df1 %>%
mutate(across(var1:var4, ~case_when(str_detect(., "^C\d+") ~ "",
TRUE ~ .), .names = 'new_{col}')) %>%
unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ')
var1 var2 var3 var4 New_Col
1 C7931 C3490 R0781 I10 R0781 I10
2 R079 R0600 I10 C3490 R079 R0600 I10
3 S270XXA S225XXA C3490 C7931 S270XXA S225XXA
我正在尝试创建一个新变量,它仅在满足特定条件时打印一系列列的第一个值。
澄清一下,我的数据库看起来像这样:
var1 | var2 | var3 | var4 |
---|---|---|---|
C7931 | C3490 | R0781 | I10 |
R079 | R0600 | I10 | C3490 |
S270XXA | S225XXA | C3490 | C7931 |
我想创建一个变量 (main),仅当值不是以 C00 到 C99 开头时才在第一个 var 列中打印该值。如果该值确实以该条件开头,那么我想测试下一列的条件,直到满足条件,然后打印该值。
因此,对于上面的 table,新创建的变量 (main) 应该看起来像这样:
var1 | var2 | var3 | var4 | main |
---|---|---|---|---|
C7931 | C3490 | R0781 | I10 | R0781 |
R079 | R0600 | I10 | C3490 | R079 |
C0258 | S225XXA | C3490 | C7931 | S225XXA |
我不太确定从哪里开始,但我怀疑这可能涉及 mutate() 和 ifelse()
我们可以使用 grepl
通过遍历每一行来创建一个子集逻辑向量。匹配的模式是 C
后跟一个或多个数字 (\d+
) 并取反 (!
) 逻辑向量以对元素进行子集化,return 第一个 ([1]
)
df1$main <- apply(df1[startsWith(names(df1), "var")], 1,
function(x) x[!grepl("^C\d+", x)][1])
与 tidyverse
一起使用,可以将 rowwise
与 str_subset
library(dplyr)
library(stringr)
df1 %>%
rowwise %>%
mutate(main = first(str_subset(c_across(starts_with("var")),
regex("^C\d+"), negate = TRUE))) %>%
ungroup
# A tibble: 3 × 5
var1 var2 var3 var4 main
<chr> <chr> <chr> <chr> <chr>
1 C7931 C3490 R0781 I10 R0781
2 R079 R0600 I10 C3490 R079
3 S270XXA S225XXA C3490 C7931 S270XXA
数据
df1 <- structure(list(var1 = c("C7931", "R079", "S270XXA"), var2 = c("C3490",
"R0600", "S225XXA"), var3 = c("R0781", "I10", "C3490"), var4 = c("I10",
"C3490", "C7931")), class = "data.frame", row.names = c(NA, -3L
))
这将创建一个列,其中存储所有不满足条件的值: 来自 akrun 的数据:
library(tidyverse)
df1 %>%
mutate(across(var1:var4, ~case_when(str_detect(., "^C\d+") ~ "",
TRUE ~ .), .names = 'new_{col}')) %>%
unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ')
var1 var2 var3 var4 New_Col
1 C7931 C3490 R0781 I10 R0781 I10
2 R079 R0600 I10 C3490 R079 R0600 I10
3 S270XXA S225XXA C3490 C7931 S270XXA S225XXA