如何使用相同的功能重新编码多个数据框列
How to recode many data frame columns with same function
我有这样一个数据框:
CriterionVar Var1 Var2 Var3
3 0 0 0
1 0 0 0
2 0 0 0
5 0 0 0
我想根据 CriterionVar
的值重新编码 Var1
、Var2
和 Var3
的值。在伪代码中,它将是这样的:
for each row
if (CriterionVar.value >= Var1.index) Var1 = 1
if (CriterionVar.value >= Var2.index) Var2 = 1
if (CriterionVar.value >= Var3.index) Var3 = 1
重新编码的数据框如下所示:
CriterionVar Var1 Var2 Var3
3 1 1 1
1 1 0 0
2 1 1 0
5 1 1 1
显然,这不是完成它的方法,因为 (1) VarN
列的数量由数据值决定,并且 (2) 它很丑。
感谢任何帮助。
对于 CriterionVar 的更一般的值,您可以使用 outer
构造一个逻辑矩阵,您可以将其用于索引,如下所示:
dat[2:4][outer(dat$CriterionVar, seq_along(names(dat)[-1]), ">=")] <- 1
在这个例子中,这个returns
dat
CriterionVar Var1 Var2 Var3
1 3 1 1 1
2 1 1 0 0
3 2 1 1 0
4 5 1 1 1
第二种方法使用col
,其中returns列索引矩阵更直接一点:
dat[2:4][dat$CriterionVar >= col(dat[-1])] <- 1
和returns想要的结果。
数据
dat <-
structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(0L,
0L, 0L, 0L), Var2 = c(0L, 0L, 0L, 0L), Var3 = c(0L, 0L, 0L, 0L
)), .Names = c("CriterionVar", "Var1", "Var2", "Var3"), class = "data.frame",
row.names = c(NA, -4L))
df[,-1] = lapply(2:NCOL(df), function(i) as.numeric(df[,1] >= (i-1)))
df
# CriterionVar Var1 Var2 Var3
#1 3 1 1 1
#2 1 1 0 0
#3 2 1 1 0
#4 5 1 1 1
数据
df = structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(1,
1, 1, 1), Var2 = c(1, 0, 1, 1), Var3 = c(1, 0, 0, 1)), .Names = c("CriterionVar",
"Var1", "Var2", "Var3"), row.names = c(NA, -4L), class = "data.frame")
我是 vapply
的大力支持者:它速度很快,而且您知道它的形状 return。唯一的问题是生成的矩阵通常是您想要的 "sideways" 版本。但是 t()
很容易解决这个问题。
n_var_cols <- 3
truncated_criterion <- pmin(dat[["CriterionVar"]], n_var_cols)
row_template <- rep_len(0, n_var_cols)
replace_up_to_index <- function(index) {
replace(row_template, seq_len(index), 1)
}
over_matrix <- vapply(
X = truncated_criterion,
FUN = replace_up_to_index,
FUN.VALUE = row_template
)
over_matrix <- t(over_matrix)
dat[, -1] <- over_matrix
dat
# CriterionVar Var1 Var2 Var3
# 1 3 1 1 1
# 2 1 1 0 0
# 3 2 1 1 0
# 4 5 1 1 1
前三行有一些簿记,但没有什么太糟糕的。我使用 pmin()
将条件值限制为不大于 VarN
列的数量。
我有这样一个数据框:
CriterionVar Var1 Var2 Var3
3 0 0 0
1 0 0 0
2 0 0 0
5 0 0 0
我想根据 CriterionVar
的值重新编码 Var1
、Var2
和 Var3
的值。在伪代码中,它将是这样的:
for each row
if (CriterionVar.value >= Var1.index) Var1 = 1
if (CriterionVar.value >= Var2.index) Var2 = 1
if (CriterionVar.value >= Var3.index) Var3 = 1
重新编码的数据框如下所示:
CriterionVar Var1 Var2 Var3
3 1 1 1
1 1 0 0
2 1 1 0
5 1 1 1
显然,这不是完成它的方法,因为 (1) VarN
列的数量由数据值决定,并且 (2) 它很丑。
感谢任何帮助。
对于 CriterionVar 的更一般的值,您可以使用 outer
构造一个逻辑矩阵,您可以将其用于索引,如下所示:
dat[2:4][outer(dat$CriterionVar, seq_along(names(dat)[-1]), ">=")] <- 1
在这个例子中,这个returns
dat
CriterionVar Var1 Var2 Var3
1 3 1 1 1
2 1 1 0 0
3 2 1 1 0
4 5 1 1 1
第二种方法使用col
,其中returns列索引矩阵更直接一点:
dat[2:4][dat$CriterionVar >= col(dat[-1])] <- 1
和returns想要的结果。
数据
dat <-
structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(0L,
0L, 0L, 0L), Var2 = c(0L, 0L, 0L, 0L), Var3 = c(0L, 0L, 0L, 0L
)), .Names = c("CriterionVar", "Var1", "Var2", "Var3"), class = "data.frame",
row.names = c(NA, -4L))
df[,-1] = lapply(2:NCOL(df), function(i) as.numeric(df[,1] >= (i-1)))
df
# CriterionVar Var1 Var2 Var3
#1 3 1 1 1
#2 1 1 0 0
#3 2 1 1 0
#4 5 1 1 1
数据
df = structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(1,
1, 1, 1), Var2 = c(1, 0, 1, 1), Var3 = c(1, 0, 0, 1)), .Names = c("CriterionVar",
"Var1", "Var2", "Var3"), row.names = c(NA, -4L), class = "data.frame")
我是 vapply
的大力支持者:它速度很快,而且您知道它的形状 return。唯一的问题是生成的矩阵通常是您想要的 "sideways" 版本。但是 t()
很容易解决这个问题。
n_var_cols <- 3
truncated_criterion <- pmin(dat[["CriterionVar"]], n_var_cols)
row_template <- rep_len(0, n_var_cols)
replace_up_to_index <- function(index) {
replace(row_template, seq_len(index), 1)
}
over_matrix <- vapply(
X = truncated_criterion,
FUN = replace_up_to_index,
FUN.VALUE = row_template
)
over_matrix <- t(over_matrix)
dat[, -1] <- over_matrix
dat
# CriterionVar Var1 Var2 Var3
# 1 3 1 1 1
# 2 1 1 0 0
# 3 2 1 1 0
# 4 5 1 1 1
前三行有一些簿记,但没有什么太糟糕的。我使用 pmin()
将条件值限制为不大于 VarN
列的数量。