更轻松地搜索data.frame中的列

我有一个像下面这样的数据库

Var1 Var2 Var3 X Y Z
VIX  SPX  VOL  2 3 4
SPX  VIX  NA   4 4 NA
SPX  NA   NA   2 NA NA

我希望将第一行与用户的输入隔离为VIX,SPX和VOL . 但是,在这样的数据库中,我不知道这些变量保存在哪个组合中 .

那就是我们可能有VIX作为Var1,SPX作为Var2,VOL作为Var3,或者我们可能有VOL作为Var1,SPX作为Var2和VIX作为Var3 . 在这种情况下,6种组合是可能的 .

我可以连接字符串以在R中创建所有6种可能性并进行一行查找 . 但我正在寻找一种更简单的算法 .

我试图使用子集来过滤一列接一列,但同样麻烦 . 在R中是否有更简单的方法

回答(3)

2 years ago

我们可以对前三列使用 apply 行,如果它具有三个可能值中的任何一个,则检查 grepl ,最后使用 all ,我们验证该行的所有三列都具有可接受的值 .

df[apply(df[1:3], 1, function(x) all(grepl("VIX|SPX|VOL", x))), ]

#   Var1 Var2 Var3 X Y Z
#1  VIX  SPX  VOL  2 3 4

或者正如@Cath在评论中提到的使用上述内容可能会导致选择一些不必要的行 . 我们可以改成它

df[apply(df[1:3], 1, function(x) all(c("VIX", "SPX", "VOL") %in% x)), ]

确保三列中存在所有三个唯一值 .

2 years ago

你也可以试试 data.table 包:

library(data.table)
setDT(df)[df[, all(c("VIX", "SPX", "VOL") %in% c(Var1, Var2, Var3)), by=1:3]$V1]
#   Var1 Var2 Var3 X Y Z
#1:  VIX  SPX  VOL 2 3 4

条件 all(c("VIX", "SPX", "VOL") %in% c(Var1, Var2, Var3) 允许确保3个变量中存在所有3个值(避免在可能发生的情况下选择具有例如 VIX VIX VOL 的行) .

2 years ago

我们可以使用矢量化 rowSums

df1[rowSums(Reduce(`|`, lapply(c("VIX", "SPX", "VOL"), `==`, df1[1:3])), na.rm = TRUE)==3,]
#  Var1 Var2 Var3 X Y Z
#1  VIX  SPX  VOL 2 3 4

或者另一种矢量化方法,而不是循环遍历行 .

df1[!rowSums(Vectorize(function(x) !x%in% c("VIX", "SPX", "VOL"))(df1[1:3])),]
#  Var1 Var2 Var3 X Y Z
#1  VIX  SPX  VOL 2 3 4