R: 从条件列表中创建指标列。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了R: 从条件列表中创建指标列。相关的知识,希望对你有一定的参考价值。
我有一个数据框和一些条件。每个条件都应该检查数据框中某一列的值是否在一组有效值之内。
这就是我所尝试的。
# create the sample dataframe
age <- c(120, 45)
sex <- c("x", "f")
df <-data.frame(age, sex)
# create the sample conditions
conditions <- list(
list("age", c(18:100)),
list("sex", c("f", "m"))
)
addIndicator <- function (df, columnName, validValues) {
indicator <- vector()
for (row in df[, toString(columnName)]) {
# for some strange reason, %in% doesn't work correctly here, but always returns FALSe
indicator <- append(indicator, row %in% validValues)
}
df <- cbind(df, indicator)
# rename the column
names(df)[length(names(df))] <- paste0("I_", columnName)
return(df)
}
for (condition in conditions){
columnName <- condition[1]
validValues <- condition[2]
df <- addIndicator(df, columnName, validValues)
}
print(df)
然而,这导致所有的条件都被认为是不满足的 - 这不是我所期望的。
age sex I_age I_sex
1 120 x FALSE FALSE
2 45 f FALSE FALSE
我想 %in%
没有返回预期的结果。我检查了 typeof(row)
并试图将其归纳为一个最小的例子。在一个简单的ME中,如果变量的类型和值相同,那么 %in%
正常工作。所以,在我尝试应用这个的上下文中,一定有什么问题。由于这是我第一次尝试用R写任何东西,我被卡在这里。
我到底做错了什么,如何才能达到我想要的目的?
答案
如果你喜欢使用 整洁的世界 包系列。
library(tidyverse)
allowed_values <- list(age = 18:100, sex = c("f", "m"))
df %>%
imap_dfr(~ .x %in% allowed_values[[.y]]) %>%
rename_with(~ paste0('I_', .x)) %>%
bind_cols(df)
imap_dfr
允许你操纵每一列的 df
使用lambda函数。.x
引用列的内容和 .y
引用名称。
rename_with
使用另一个lambda函数重命名列和 bind_cols
将结果与原始数据框结合起来。
我从Ben的回答中借用了简化的条件列表。我发现我的方法略微更易读,但这是一个品味问题,也是你是否已经在其他地方使用tidyverse的问题。
另一答案
conditions
显得是一个嵌套的列表。当你在你的答案中使用:
validValues <- condition[2]
在你的 for
循环,你的结果也是一个列表。
要得到值的向量,以便使用 %in%
,您可以提取 [[
通过。
validValues <- condition[[2]]
获取指标的简化方法可以是一个简单的列表。
conditions_lst <- list(age = 18:100, sex = c("f", "m"))
并使用 sapply
而非 for
循环。
cbind(df, sapply(setNames(names(df), paste("I", names(df), sep = "_")), function(x) {
df[[x]] %in% conditions_lst[[x]]
}))
输出
age sex I_age I_sex
1 120 x FALSE FALSE
2 45 f TRUE TRUE
以上是关于R: 从条件列表中创建指标列。的主要内容,如果未能解决你的问题,请参考以下文章