基于 r 中的字符向量创建虚拟对象
Create dummy based on character vectors in r
如果所有条目(在 cols value_1_value_3 中)都等于给定字符(例如 "C")或者是 NA,我想创建一个虚拟变量。
玩具示例:
df <- data.frame(state=rep("state"),
candidate=c("a","b","c"),
value_1= c("A","B","C"),
value_2= c("A","B",NA),
value_3= c("C",NA,NA), stringsAsFactors = FALSE)
需求:
df <- data.frame(state=rep("state"),
candidate=c("a","b","c"),
value_1= c("A","B","C"),
value_2= c("A","B",NA),
value_3= c("C",NA,NA),
dummy=c(0,0,1),stringsAsFactors = FALSE)
我试过了(但没用):
df$dummy <- ifelse(df[-(1:2)] %in% c("C","NA"),1,0)
我们可以使用 apply
row-wise 并检查 all
所选列中的条目是否等于 "C"
,忽略 NA
值。
cols <- grep("^value", names(df))
df$dummy <- as.integer(apply(df[cols] == "C", 1, all, na.rm = TRUE))
df
# state candidate value_1 value_2 value_3 dummy
#1 state a A A C 0
#2 state b B B <NA> 0
#3 state c C <NA> <NA> 1
就您的尝试而言,%in%
不适用于整个数据框,您需要使用 sapply
/lapply
检查多列中的值。事实上你可以在这里避免ifelse
df$dummy <- as.integer(sapply(df[-c(1:2)], function(x) all(x %in% c(NA, "C"))))
另一种方式:
rowSums(df[-(1:2)] != "C", na.rm=TRUE) == 0
# [1] FALSE FALSE TRUE
工作原理:
- 制作非"C"值的检查矩阵
- 按行计算非"C"值,跳过 NAs
- 如果计数为0,则为真;否则,假
令人困惑的是,df[-(1:2)] == "C"
产生了一个矩阵,而 df[-(1:2)] %in% "C"
则没有。要处理后者,请先包装 as.matrix(df[-(1:2)])
。
一个选项使用tidyverse
library(tidyverse)
df %>%
mutate(dummy = pmap_int(select(., value_1, value_3),
~ +(!sum(c(...) != "C", na.rm = TRUE))))
# state candidate value_1 value_2 value_3 dummy
#1 state a A A C 0
#2 state b B B <NA> 0
#3 state c C <NA> <NA> 1
如果所有条目(在 cols value_1_value_3 中)都等于给定字符(例如 "C")或者是 NA,我想创建一个虚拟变量。
玩具示例:
df <- data.frame(state=rep("state"),
candidate=c("a","b","c"),
value_1= c("A","B","C"),
value_2= c("A","B",NA),
value_3= c("C",NA,NA), stringsAsFactors = FALSE)
需求:
df <- data.frame(state=rep("state"),
candidate=c("a","b","c"),
value_1= c("A","B","C"),
value_2= c("A","B",NA),
value_3= c("C",NA,NA),
dummy=c(0,0,1),stringsAsFactors = FALSE)
我试过了(但没用):
df$dummy <- ifelse(df[-(1:2)] %in% c("C","NA"),1,0)
我们可以使用 apply
row-wise 并检查 all
所选列中的条目是否等于 "C"
,忽略 NA
值。
cols <- grep("^value", names(df))
df$dummy <- as.integer(apply(df[cols] == "C", 1, all, na.rm = TRUE))
df
# state candidate value_1 value_2 value_3 dummy
#1 state a A A C 0
#2 state b B B <NA> 0
#3 state c C <NA> <NA> 1
就您的尝试而言,%in%
不适用于整个数据框,您需要使用 sapply
/lapply
检查多列中的值。事实上你可以在这里避免ifelse
df$dummy <- as.integer(sapply(df[-c(1:2)], function(x) all(x %in% c(NA, "C"))))
另一种方式:
rowSums(df[-(1:2)] != "C", na.rm=TRUE) == 0
# [1] FALSE FALSE TRUE
工作原理:
- 制作非"C"值的检查矩阵
- 按行计算非"C"值,跳过 NAs
- 如果计数为0,则为真;否则,假
令人困惑的是,df[-(1:2)] == "C"
产生了一个矩阵,而 df[-(1:2)] %in% "C"
则没有。要处理后者,请先包装 as.matrix(df[-(1:2)])
。
一个选项使用tidyverse
library(tidyverse)
df %>%
mutate(dummy = pmap_int(select(., value_1, value_3),
~ +(!sum(c(...) != "C", na.rm = TRUE))))
# state candidate value_1 value_2 value_3 dummy
#1 state a A A C 0
#2 state b B B <NA> 0
#3 state c C <NA> <NA> 1