将相同的因子水平应用于R中水平不同的多个变量
我有一个将相同的因子水平应用于R中水平不同的多个变量,r,data.table,factors,levels,R,Data.table,Factors,Levels,我有一个数据表,其中包含168个变量和8278个观察值。变量69:135最初存储为字符串。他们应该成为地区傀儡,我希望最终达到2级(=是,公司在这里经营)和1级(=否,公司不在这里经营)。问题在于原始变量中有三种不同的输入组合:1)“真”、“1”、“0”、“假”,2“真”、“假”,以及3“1”、“0”。此外,大约5个变量只有一个值,即“0”或“1”。此处给出了一个示例: #generating replicable data structure(list( region1 = structu
数据表
,其中包含168个变量
和8278个观察值
。变量69:135
最初存储为字符串。他们应该成为地区傀儡,我希望最终达到2级(=是,公司在这里经营)和1级(=否,公司不在这里经营)。问题在于原始变量中有三种不同的输入组合:1)“真”、“1”、“0”、“假”,2“真”、“假”,以及3“1”、“0”。此外,大约5个变量只有一个值,即“0”或“1”。此处给出了一个示例:
#generating replicable data
structure(list(
region1 = structure(c("TRUE", "FALSE", "0", "1", NA), class = "character"),
region2 = structure(c("1", "1", "0", NA, NA), class = "character"),
region3 = structure(c(NA, "FALSE", "TRUE", NA, "FALSE"), class = "character"),
region4 = structure(c(NA, "0", "0", NA, "0"), class = "character")),
.Names = c("region1", "region2", "region3", "region4"), row.names = c(NA, 5), class = "data.table")
#this gives:
# region1 region2 region3 region4
#1 TRUE 1 <NA> <NA>
#2 FALSE 1 FALSE 0
#3 0 0 TRUE 0
#4 1 <NA> <NA> <NA>
#5 <NA> <NA> FALSE 0
我已经看过了
和
然而,这对我没有帮助
我使用嵌套的ifelse()
命令尝试了以下操作:
library(data.table)
library(forcats)
check <- cbind(dt[1:68], as.data.table(apply(dt[69:135], 2, function(x) {
ifelse("1" %in% x & "TRUE" %in% x,
fct_collapse(x,
"2" = c("TRUE",
"1"),
"1" = c("FALSE",
"0")
),
ifelse("1" %in% x & !("TRUE" %in% x),
fct_collapse(x,
"2" = "1",
"1" = "0"),
fct_collapse(x,
"2" = "TRUE",
"1" = "FALSE"
)))
}
)), dt[136:168])
单独使用,并且在未与fct\u collapse
组合时,嵌套的ifelse()
命令执行以下操作:
#the ifelse statement works
ifelse("TRUE" %in% dt$region1, 2, "FALSE")
ifelse(5 %in% dt$region1, 2, "FALSE")
#also the nested ifelse statement works
ifelse("1" %in% dt$region1 & "TRUE" %in% dt$region1,
0,
ifelse("1" %in% dt$region1 & !("TRUE" %in% dt$region1),
1,
2
))
ifelse("1" %in% dt$region2 & "TRUE" %in% dt$region2,
0,
ifelse("1" %in% dt$region2 & !("TRUE" %in% dt$region2),
1,
2
))
有人知道如何解决这个问题吗
非常感谢您提前提出的建议 这里有一种在
for
循环中调用set()
的方法
library(data.table)
f <- function(x){
x <- as.character(x)
i1 <- x %in% c("TRUE", "1")
i0 <- x %in% c("FALSE", "0")
x[which(i1)] <- "2"
x[which(i0)] <- "1"
as.integer(x)
}
for (j in seq_along(dt)) set(dt, j = j, value = f(dt[[j]]))
dt
# region1 region2 region3 region4
#1: 2 2 NA NA
#2: 1 2 1 1
#3: 1 1 2 1
#4: 2 NA NA NA
#5: NA NA 1 1
我认为您可以删除
for
循环并传递集合(dt,names(dt),lappy(dt,f))
,否?或者干脆lappy(dt,f)
:)@jangorecki谢谢,请看编辑。作为评论发布,我会回复。非常感谢你的这种方法,鲁伊·巴拉达斯和@jangorecki指出了进一步的简化。这太容易了!使用函数和dt[,name(dt[,69:135]):=lappy(dt[,69:135],adjust_factor_levels)]工作:
#the ifelse statement works
ifelse("TRUE" %in% dt$region1, 2, "FALSE")
ifelse(5 %in% dt$region1, 2, "FALSE")
#also the nested ifelse statement works
ifelse("1" %in% dt$region1 & "TRUE" %in% dt$region1,
0,
ifelse("1" %in% dt$region1 & !("TRUE" %in% dt$region1),
1,
2
))
ifelse("1" %in% dt$region2 & "TRUE" %in% dt$region2,
0,
ifelse("1" %in% dt$region2 & !("TRUE" %in% dt$region2),
1,
2
))
library(data.table)
f <- function(x){
x <- as.character(x)
i1 <- x %in% c("TRUE", "1")
i0 <- x %in% c("FALSE", "0")
x[which(i1)] <- "2"
x[which(i0)] <- "1"
as.integer(x)
}
for (j in seq_along(dt)) set(dt, j = j, value = f(dt[[j]]))
dt
# region1 region2 region3 region4
#1: 2 2 NA NA
#2: 1 2 1 1
#3: 1 1 2 1
#4: 2 NA NA NA
#5: NA NA 1 1
dt[, names(dt) := lapply(dt, f)]