R:将几列从 [1,2] 转换为布尔值 [TRUE,FALSE]
R: Convert several columns from [1,2] to Boolean [TRUE,FALSE]
我有一个数据框(用 read.csv 导入),它有很多列,但不是所有列,这些列具有编码为 1=false、2=true 的布尔数据。
我想将它们全部转换为布尔值。我知道我能做到
data$someCol <- data$someCol == 2
我的问题:
- 这是最好的方法吗?
- 是否有另一个我可以在其中指定“1”表示 FALSE,“2”表示 TRUE,其余为 NA?
- 我能以某种方式 "mass-process" 这样的列,通过 grep 选择吗?
谢谢!
你可以将非1或2的元素转换为NA
,只需使用逻辑条件df1==2
将其转换为TRUE
为2的逻辑矩阵,FALSE
为1,其余为NA
is.na(df1) <- !(df1==1|df1==2)
df1==2
对于大型数据集,最好使用lapply
遍历列
df1[] <- lapply(df1, function(x) {x[!x %in% c(1,2)] <- NA
x==2})
更新
如果我们只想应用列名以 'XX' 开头的列的子集,grep
可以选择对列进行子集化,然后在该列上循环 lapply
列的子集并将该列替换为 lapply
.
的输出
indx <- grep('^XX', colnames(df2))
df2[indx] <- lapply(df2[indx], function(x) {x[!x %in% c(1,2)] <- NA
x==2})
另一种选择是使用 dplyr
中的 mutate_each
library(dplyr)
mutate_each(df2, funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
我们 select 名称以 XX (matches('^XX')
) 开头的列,在 funs
内创建逻辑条件。 .
表示列中的任何元素。
. %in% 1:2
给出一个逻辑输出。如果元素是 1 或 2,我们得到 TRUE
,如果不是 FALSE
.
(NA^!. %in% 1:2)
我们取反(!
)TRUE/FALSE
的输出,使TRUE变为FALSE,FALSE变为TRUE,将TRUE的值变为NA(NA^!...
),从而转换值对于 NA 不是 1 或 2,所有其他值都为 1。
*.==2
然后我们将 *
我们从早期输出中得到的值相乘,这样 NA 值保持为 NA 并且 1 值更改为该位置的值,例如1*2=2
。这可以通过 .==2
变成逻辑输出。如果值为 2,则 return 为 TRUE,否则(即 1)return FALSE。
使用mutate_each
不会改变原来的对象,除非我们给原来的对象赋值
df2 <- mutate_each(df2, funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
另一个无需重新分配的选项是使用 magrittr
中的 %<>%
运算符
library(magrittr)
df2 %<>%
mutate_each(funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
数据
set.seed(24)
df1 <- as.data.frame(matrix(sample(1:5, 20*5, replace=TRUE), ncol=5))
df2 <- df1
colnames(df2)[c(2,4)] <- paste0('XX', 1:2)
我有一个数据框(用 read.csv 导入),它有很多列,但不是所有列,这些列具有编码为 1=false、2=true 的布尔数据。
我想将它们全部转换为布尔值。我知道我能做到
data$someCol <- data$someCol == 2
我的问题:
- 这是最好的方法吗?
- 是否有另一个我可以在其中指定“1”表示 FALSE,“2”表示 TRUE,其余为 NA?
- 我能以某种方式 "mass-process" 这样的列,通过 grep 选择吗?
谢谢!
你可以将非1或2的元素转换为NA
,只需使用逻辑条件df1==2
将其转换为TRUE
为2的逻辑矩阵,FALSE
为1,其余为NA
is.na(df1) <- !(df1==1|df1==2)
df1==2
对于大型数据集,最好使用lapply
遍历列
df1[] <- lapply(df1, function(x) {x[!x %in% c(1,2)] <- NA
x==2})
更新
如果我们只想应用列名以 'XX' 开头的列的子集,grep
可以选择对列进行子集化,然后在该列上循环 lapply
列的子集并将该列替换为 lapply
.
indx <- grep('^XX', colnames(df2))
df2[indx] <- lapply(df2[indx], function(x) {x[!x %in% c(1,2)] <- NA
x==2})
另一种选择是使用 dplyr
mutate_each
library(dplyr)
mutate_each(df2, funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
我们 select 名称以 XX (matches('^XX')
) 开头的列,在 funs
内创建逻辑条件。 .
表示列中的任何元素。
. %in% 1:2
给出一个逻辑输出。如果元素是 1 或 2,我们得到 TRUE
,如果不是 FALSE
.
(NA^!. %in% 1:2)
我们取反(!
)TRUE/FALSE
的输出,使TRUE变为FALSE,FALSE变为TRUE,将TRUE的值变为NA(NA^!...
),从而转换值对于 NA 不是 1 或 2,所有其他值都为 1。
*.==2
然后我们将 *
我们从早期输出中得到的值相乘,这样 NA 值保持为 NA 并且 1 值更改为该位置的值,例如1*2=2
。这可以通过 .==2
变成逻辑输出。如果值为 2,则 return 为 TRUE,否则(即 1)return FALSE。
使用mutate_each
不会改变原来的对象,除非我们给原来的对象赋值
df2 <- mutate_each(df2, funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
另一个无需重新分配的选项是使用 magrittr
%<>%
运算符
library(magrittr)
df2 %<>%
mutate_each(funs((NA^!. %in% 1:2)*.==2), matches('^XX'))
数据
set.seed(24)
df1 <- as.data.frame(matrix(sample(1:5, 20*5, replace=TRUE), ncol=5))
df2 <- df1
colnames(df2)[c(2,4)] <- paste0('XX', 1:2)