当其他几个列中的任何一个的值为 TRUE(或 1)时,使用 mutate() 创建新列
create new column with mutate() when value in any of several other columns is TRUE (or 1)
我有一个包含 5 列的数据框 (my_dataframe)。都有 0 或 1 个值。我想创建一个名为 cn7_any 的新列,当列 2:5 中的任何值为 ==1 时,该列的值应为 1。
structure(list(cn7_normal = c(1L, 1L, 1L, 1L, 1L, 1L),
cn7_right_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_right_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L)),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))
> head(my_dataframe)
# A tibble: 6 x 5
cn7_normal cn7_right_paralysis_cen… cn7_right_paralysis_perip… cn7_left_paralysis_cen… cn7_left_paralysis_peri…
<int> <int> <int> <int> <int>
1 1 0 0 0 0
2 1 0 0 0 0
我可以用 case_when() 成功地做到这一点:
my_dataframe<-my_dataframe%>%
mutate(cn7_paralisis_any=case_when(cn7_right_paralysis_central==1 ~ 1,
cn7_right_paralysis_peripheral==1 ~ 1,
cn7_left_paralysis_central==1 ~ 1,
cn7_left_paralysis_peripheral==1 ~ 1,
TRUE ~ 0)
)
虽然有效,但我想知道是否有更简单、更简洁的解决方案。我觉得我应该以某种方式使用 any() 。有什么想法吗?
my_dataframe$cn7_any <- apply(my_dataframe[ , 2:5], 1, max)
你的数据全为零,所以我会改变一对来证明这一点。
rowSums(my_dataframe[,2:5]) > 0
# [1] FALSE TRUE FALSE TRUE FALSE FALSE
+(rowSums(my_dataframe[,2:5]) > 0)
# [1] 0 1 0 1 0 0
my_dataframe$cn7_any <- +(rowSums(my_dataframe[,2:5]) > 0)
在dplyr
,
内
my_dataframe %>%
mutate(cn7_any = rowSums(across(-cn7_normal, ~ . > 0)) > 0)
# # A tibble: 6 x 6
# cn7_normal cn7_right_paralysis_central cn7_right_paralysis_peripheral cn7_left_paralysis_central cn7_left_paralysis_peripheral cn7_any
# <int> <int> <int> <int> <int> <lgl>
# 1 1 0 0 0 0 FALSE
# 2 1 0 0 0 1 TRUE
# 3 1 0 0 0 0 FALSE
# 4 1 0 0 1 0 TRUE
# 5 1 0 0 0 0 FALSE
# 6 1 0 0 0 0 FALSE
您正在做的事情似乎是 logical
,而不是数字,但是如果您想要数字,只需使用上面的 +(.)
技巧即可:
my_dataframe %>%
mutate(cn7_any = +(rowSums(across(-cn7_normal, ~ . > 0)) > 0))
类似于
我还更改了您数据集中的一些数字。
V2:使用或 |
V3:在 mutate
之前使用 dplyr::rowwise()
有效地按行对输入进行分组,然后使用 all()
函数(all
查看整个向量,这这就是为什么你会得到意想不到的结果)
my_dataframe<-structure(list(cn7_normal = c(1L, 1L, 1L, 1L, 1L, 1L),
cn7_right_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_right_paralysis_peripheral = c(1L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_central = c(0L, 1L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L)),
row.names = c(NA, -6L),
class = c("tbl_df", "tbl", "data.frame"))
my_dataframe%>%
rowwise() %>% ### rowwise ###
mutate(cn7_paralisis_any=case_when(cn7_right_paralysis_central==1 ~ 1,
cn7_right_paralysis_peripheral==1 ~ 1,
cn7_left_paralysis_central==1 ~ 1,
cn7_left_paralysis_peripheral==1 ~ 1,
TRUE ~ 0),
cn7_v2=(cn7_right_paralysis_central|cn7_right_paralysis_peripheral|cn7_left_paralysis_central|cn7_left_paralysis_peripheral),
cn7_v3=any(cn7_right_paralysis_central ,cn7_right_paralysis_peripheral, cn7_left_paralysis_central, cn7_left_paralysis_peripheral)
) %>%
select(cn7_paralisis_any,cn7_v2,cn7_v3)
# A tibble: 6 x 3
# Rowwise:
# cn7_paralisis_any cn7_v2 cn7_v3
# <dbl> <lgl> <lgl>
#1 1 TRUE TRUE
#2 1 TRUE TRUE
#3 0 FALSE FALSE
#4 0 FALSE FALSE
#5 0 FALSE FALSE
#6 0 FALSE FALSE
我现在在这种情况下使用 dplyr::if_any
和 dplyr::if_all
。我认为每当我们必须在 dplyr 中执行这种按行逻辑操作时,它使代码非常清晰和可读。
对于这种特殊情况,我现在将使用:
library(dplyr)
my_dataframe %>%
mutate(cn7_paralisis_any = +if_any(across(-cn7_normal)))
我有一个包含 5 列的数据框 (my_dataframe)。都有 0 或 1 个值。我想创建一个名为 cn7_any 的新列,当列 2:5 中的任何值为 ==1 时,该列的值应为 1。
structure(list(cn7_normal = c(1L, 1L, 1L, 1L, 1L, 1L),
cn7_right_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_right_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L)),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))
> head(my_dataframe)
# A tibble: 6 x 5
cn7_normal cn7_right_paralysis_cen… cn7_right_paralysis_perip… cn7_left_paralysis_cen… cn7_left_paralysis_peri…
<int> <int> <int> <int> <int>
1 1 0 0 0 0
2 1 0 0 0 0
我可以用 case_when() 成功地做到这一点:
my_dataframe<-my_dataframe%>%
mutate(cn7_paralisis_any=case_when(cn7_right_paralysis_central==1 ~ 1,
cn7_right_paralysis_peripheral==1 ~ 1,
cn7_left_paralysis_central==1 ~ 1,
cn7_left_paralysis_peripheral==1 ~ 1,
TRUE ~ 0)
)
虽然有效,但我想知道是否有更简单、更简洁的解决方案。我觉得我应该以某种方式使用 any() 。有什么想法吗?
my_dataframe$cn7_any <- apply(my_dataframe[ , 2:5], 1, max)
你的数据全为零,所以我会改变一对来证明这一点。
rowSums(my_dataframe[,2:5]) > 0
# [1] FALSE TRUE FALSE TRUE FALSE FALSE
+(rowSums(my_dataframe[,2:5]) > 0)
# [1] 0 1 0 1 0 0
my_dataframe$cn7_any <- +(rowSums(my_dataframe[,2:5]) > 0)
在dplyr
,
my_dataframe %>%
mutate(cn7_any = rowSums(across(-cn7_normal, ~ . > 0)) > 0)
# # A tibble: 6 x 6
# cn7_normal cn7_right_paralysis_central cn7_right_paralysis_peripheral cn7_left_paralysis_central cn7_left_paralysis_peripheral cn7_any
# <int> <int> <int> <int> <int> <lgl>
# 1 1 0 0 0 0 FALSE
# 2 1 0 0 0 1 TRUE
# 3 1 0 0 0 0 FALSE
# 4 1 0 0 1 0 TRUE
# 5 1 0 0 0 0 FALSE
# 6 1 0 0 0 0 FALSE
您正在做的事情似乎是 logical
,而不是数字,但是如果您想要数字,只需使用上面的 +(.)
技巧即可:
my_dataframe %>%
mutate(cn7_any = +(rowSums(across(-cn7_normal, ~ . > 0)) > 0))
类似于
我还更改了您数据集中的一些数字。
V2:使用或 |
V3:在 mutate
之前使用 dplyr::rowwise()
有效地按行对输入进行分组,然后使用 all()
函数(all
查看整个向量,这这就是为什么你会得到意想不到的结果)
my_dataframe<-structure(list(cn7_normal = c(1L, 1L, 1L, 1L, 1L, 1L),
cn7_right_paralysis_central = c(0L, 0L, 0L, 0L, 0L, 0L),
cn7_right_paralysis_peripheral = c(1L, 0L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_central = c(0L, 1L, 0L, 0L, 0L, 0L),
cn7_left_paralysis_peripheral = c(0L, 0L, 0L, 0L, 0L, 0L)),
row.names = c(NA, -6L),
class = c("tbl_df", "tbl", "data.frame"))
my_dataframe%>%
rowwise() %>% ### rowwise ###
mutate(cn7_paralisis_any=case_when(cn7_right_paralysis_central==1 ~ 1,
cn7_right_paralysis_peripheral==1 ~ 1,
cn7_left_paralysis_central==1 ~ 1,
cn7_left_paralysis_peripheral==1 ~ 1,
TRUE ~ 0),
cn7_v2=(cn7_right_paralysis_central|cn7_right_paralysis_peripheral|cn7_left_paralysis_central|cn7_left_paralysis_peripheral),
cn7_v3=any(cn7_right_paralysis_central ,cn7_right_paralysis_peripheral, cn7_left_paralysis_central, cn7_left_paralysis_peripheral)
) %>%
select(cn7_paralisis_any,cn7_v2,cn7_v3)
# A tibble: 6 x 3
# Rowwise:
# cn7_paralisis_any cn7_v2 cn7_v3
# <dbl> <lgl> <lgl>
#1 1 TRUE TRUE
#2 1 TRUE TRUE
#3 0 FALSE FALSE
#4 0 FALSE FALSE
#5 0 FALSE FALSE
#6 0 FALSE FALSE
我现在在这种情况下使用 dplyr::if_any
和 dplyr::if_all
。我认为每当我们必须在 dplyr 中执行这种按行逻辑操作时,它使代码非常清晰和可读。
对于这种特殊情况,我现在将使用:
library(dplyr)
my_dataframe %>%
mutate(cn7_paralisis_any = +if_any(across(-cn7_normal)))