提问人:Marlen 提问时间:12/30/2022 最后编辑:Marlen 更新时间:12/30/2022 访问量:109
在 Excel 中创建 SUMIF 函数的等效项
Creating the equivalent of a SUMIF function in Excel
问:
我有一组由最佳变量选择算法(总共 30 个候选回归器列)选择的回归器,这些回归器在数据集上运行,如下所示:
> IVs_Selected_by_LASSO
$coefficients
[1] "X4" "X10" "X19" "X20" "X22" "X25" "X27" "X28"
而且,我还在描述该数据集的结构方程中包含了一组实际回归器,最初如下所示:
True_IVs
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20
1 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1
X21 X22 X23 X24 X25 X26 X27 X28 X29 X30
1 0 1 0 0 1 1 1 1 0 1
dput(True_IVs)
structure(list(X1 = "0", X2 = "0", X3 = "0", X4 = "1", X5 = "0",
X6 = "0", X7 = "0", X8 = "0", X9 = "0", X10 = "1", X11 = "0",
X12 = "0", X13 = "1", X14 = "0", X15 = "0", X16 = "0", X17 = "0",
X18 = "0", X19 = "1", X20 = "1", X21 = "0", X22 = "1", X23 = "0",
X24 = "0", X25 = "1", X26 = "1", X27 = "1", X28 = "1", X29 = "0",
X30 = "1"), row.names = 1L, class = "data.frame")
然而,使用我提出的一个中间问题的答案,我希望他的答案能让我最终提出我正在问的当前问题,我能够将真正的结构回归器转换为一种能够与IVs_Selected_by_LASSO已经采用的格式进行逻辑比较的格式,如下所示:
True_Regressors <- names(True_IVs)[True_IVs == 1]
> True_Regressors
[1] "X4" "X10" "X13" "X19" "X20" "X22" "X25" "X26" "X27" "X28" "X30"
我是一个有经验的 Excel 用户,肯定比 R 更有经验,如果我有包含此信息的列或行,我可能会使用 SUMIF 或 IF 函数(像你一样在列的底部有一个 AUTOSUM)来解决这个问题,但我无法弄清楚如何在 R 中做同样的事情。
例如,如果我要执行 IF+AUTOSUM 解决方案并假装打印True_IVs的输出在 Excel 的 A 列中,而 IVs_Selected_by_LASSO 在 B 列中,我将使用
=IF(A1 = B1, 1, 0)
由于 A1 是 X4,B1 也是,如果我把这个 IF 函数放在 C 列中的它们旁边,我会在单元格 C1 中得到一个 1。在应用 C 列底部的 AUTOSUM 函数后,我会得到 8。
因此,对于这个例子,我想要得到一个返回 8 的函数,因为True_IVs包含 LASSO回归选择的所有 8 个变量。 此外,对于此示例,最大可能的数量为 11,因为True_IVs包含 11 个变量名,因此很明显,IVs_Selected_by_LASSO只能希望获得最多 11 个匹配项。
答:
正如其他人和我自己在评论中提到的,您有多种选择,但这里的问题似乎是 Excel 逻辑和 R 逻辑之间的脱节,因此我将尝试提供更详细的见解作为正式答案。
如您所知,您的 excel 代码:
=IF(A1 = B1, 1, 0)
将检查单个单元格以查看它是否等于单个单元格,并且可以向下复制。A1
B1
如果获取数据框(有 30 列)的列名向量,并将其视为将所有 30 个列名复制并粘贴到 excel 中的列中,我们可以将这些名称与另一个名称向量进行检查 - 这里 .除了不是单细胞与单细胞,我们可以使用以下方法检查名称是否出现在整个向量中:True_IVs
names(True_IVs)
IVs_Selected_by_LASSO$coefficients
%in%
names(True_IVs) %in% IVs_Selected_by_LASSO$coefficients
这将检查 中的每个值是否在 中的任何值中。因此,例如,如果 中的拳头值在 中的任意位置,它将返回 ,否则它将返回 。在整个向量上运行它返回一个长度为 30 的布尔向量:names(True_IVs)
IVs_Selected_by_LASSO$coefficients
names(True_IVs)
IVs_Selected_by_LASSO$coefficients
TRUE
FALSE
# [1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
# [13] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE FALSE
# [25] TRUE FALSE TRUE TRUE FALSE FALSE
其值对应于是否在向量中的任何位置找到 中的每个元素。names(True_IVs)
IVs_Selected_by_LASSO$coefficients
其次,正如注释中所指出的,当对 R 求和时,假设 和 ,因此将其包装在 a 中将返回包含的总数:TRUE == 1
FALSE == 0
sum
sum(names(True_IVs) %in% IVs_Selected_by_LASSO$coefficients)
# [1] 8
这提供了更大的灵活性,尤其是在值无序的情况下。例如,如果我们将值打乱为随机顺序:
IVs_Selected_by_LASSO$coefficients <- sample(IVs_Selected_by_LASSO$coefficients, length(IVs_Selected_by_LASSO$coefficients))
我们得到相同的结果:
sum(names(True_IVs) %in% IVs_Selected_by_LASSO$coefficients)
# [1] 8
当然,还有其他多种方法可以做到这一点,例如@G.格罗滕迪克提到优雅地使用和:length
intersect
length(intersect(IVs_Selected_by_LASSO$coefficients, names(True_IVs))) # Thanks G. Grothendieck
# [1] 8
或者更不优雅地使用 with 而不是:length
names(True_IVs)
sum
length(names(True_IVs)[names(True_IVs) %in% IVs_Selected_by_LASSO$coefficients])
# [1] 8
希望这有帮助!
评论
如果您尝试计算两者共有的元素数,然后IVs_Selected_by_LASSO$coefficients
True_Regressors
length(intersect(IVs_Selected_by_LASSO$coefficients, True_Regressors))
intersect
不要求参数的内容顺序相同。
请注意,有一个名为 ExcelFunctionsR 的 R 包,如果你用谷歌搜索 R SUMIF,你会得到一些点击。
评论
length(names(True_IVs)[True_IVs == 1])
sum(as.numeric(True_IVs[True_IVs == 1]))
sum
True_Regressors
length
sum( True_Regressors %in% IVs_Selected_by_LASSO$coefficients)
[1] 8
IVs_Selected_by_LASSO$coefficients
True_IVs == 1
IVs_Selected_by_LASSO$coefficients
True_IVs