【发布时间】:2016-10-13 09:11:13
【问题描述】:
我正在尝试对因子水平频率超过 10 的数据框进行子集化。
如果 dogs 是数据框中某个特征的名称:
不起作用:
somevar <- "dogs"
df <- subset(df, with(df, somevar %in% names(which(table(somevar)>=10))))
返回 0 个观测值的 df
有效:
df <- subset(df, with(df, dogs %in% names(which(table(dogs)>=10))))
返回 df 并减少几行,因为那些频率小于 10 的狗的级别已被删除
有什么区别,为什么第二个有效,而前一个无效?
由于我需要遍历数据框中的特征,我需要不起作用的方法来工作!我想将特征名称向量传递给 for 循环
可重现的例子:
vegetables <- c("carrots", "carrots", "carrots", "carrots", "carrots")
animals <- c("cats", "dogs", "dogs", "fish", "cats")
df <- data.frame(vegetables, animals)
df
vegatables animals
1 carrots cats
2 carrots dogs
3 carrots dogs
4 carrots fish
5 carrots cats
> str(df)
'data.frame': 5 obs. of 2 variables:
$ vegatables: Factor w/ 1 level "carrots": 1 1 1 1 1
$ animals : Factor w/ 3 levels "cats","dogs",..: 1 2 2 3 1
我想删除任何因子特征观察频率小于 2 的观察值。在这种情况下,动物因子中水平鱼的频率为 1,因此我希望 df 减少一个观察值:
> test <- subset(df, with(df, animals %in% names(which(table(animals) >= 2))))
> test
vegatables animals
1 carrots cats
2 carrots dogs
3 carrots dogs
5 carrots cats
太棒了。
除非我这样做时它不起作用:
categoricals <- names(df)
for ( i in categoricals ) {
test <- subset(df, with(df, i %in% names(which(table(i) >= 10))))
}
返回一个空的数据框df。我希望它返回的结果与上面的测试 df 完全相同。
类似的:
i <- "animals"
test <- subset(df, with(df, i %in% names(which(table(i) >= 2))))
> test
[1] vegatables animals
<0 rows> (or 0-length row.names)
我希望最后一个示例能够像我直接在 with 函数中输入动物时那样工作。
【问题讨论】:
-
我认为问题在于,您在循环中覆盖了
df。因此,在第二次迭代中,您的df将已经为空。因此将结果存储在其他变量中将是一个解决方案。 -
嗨@BenjaminMohn,我在问题中添加了更多内容。它甚至不是 for 循环。请参阅上面的“不起作用/起作用”
-
@Hugh 我该怎么办?我尝试 eval(somevar) 代替仅使用 somevar 但没有运气
-
您能提供示例数据和预期输出吗?目前尚不清楚
df是什么样的。 -
@hugh 是的,我现在已经添加了