在 data.frame 中跨列搜索的更简单解决方案
Easier solution for searching across columns in 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 种可能性并进行行查找。但我正在寻找更简单的算法。
我正在尝试使用 subset in 来筛选一列又一列,但这同样很麻烦。在 R
中有更简单的出路吗
我们可以对前三列按行使用 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)), ]
确保所有三个唯一值都出现在三列中。
我们可以使用矢量化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
您也可以尝试使用 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 个变量中(避免 select 一行,例如 VIX VIX VOL
,以防可能发生)。
我有一个像下面这样的数据库
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 种可能性并进行行查找。但我正在寻找更简单的算法。
我正在尝试使用 subset in 来筛选一列又一列,但这同样很麻烦。在 R
中有更简单的出路吗我们可以对前三列按行使用 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)), ]
确保所有三个唯一值都出现在三列中。
我们可以使用矢量化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
您也可以尝试使用 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 个变量中(避免 select 一行,例如 VIX VIX VOL
,以防可能发生)。