为了说明我的问题,一个虚拟的例子:我有一个16行的数据集(这些代表试验)和3列(试验难度,标签X和标签Y)。标签X是4级(1-4)的因子,标签Y是2级的因子("女性","男性")。例如:
difficulty X Y
trial1 3.0 1 male
trial2 1.4 1 male
trial3 2.1 1 female
trial4 1.5 1 female
trial5 0.3 2 male
trial6 1.2 2 male
trial7 3.0 2 female
trial8 1.6 2 female
trial9 0.8 3 male
trial10 1.4 3 male
trial11 2.8 3 female
trial12 1.5 3 female
trial13 0.3 4 male
trial14 1.2 4 male
trial15 3.0 4 female
trial16 1.6 4 female
我想在总共16项试验中创建8项试验的子集;应符合以下标准的子集:
对于我的例子,这个虚拟例子中的理想集合是:
difficulty X Y
trial2 1.4 1 male
trial4 1.5 1 female
trial6 1.2 2 male
trial8 1.6 2 female
trial10 1.4 3 male
trial12 1.5 3 female
trial14 1.2 4 male
trial16 1.6 4 female
该子集每个X级别有2个试验,每个X级别有相同数量的雌性和雄性,而所有试验的难度值都尽可能接近1.5。
我的尝试是使用了许多嵌套的while
和if
循环,但我不确定如何同时检查两个变量(此时我正在循环直到X完成,然后循环直到Y完成,然后循环直到再次满足X,等等。这是正确的做法,还是会有更合理的方法来做到这一点?
答案 0 :(得分:3)
以下代码假设您的数据框名为dat
。代码添加一个新变量difficulty.scaled
,等于difficulty
与1.5的偏差,然后按X和Y的值对数据进行分组,然后在每个组中选择绝对值为{{1最接近0的(即最接近1.5的difficulty.scaled
)。
您可以调整difficulty
函数的probs
参数,以选择所需的每个子组的百分比。在这种情况下,我已经选择了每个子组中50%的行(即,代表quantile
和X
的每个组合的行的50%。)
Y
对于您在上面粘贴的数据(我已将试用版转换为变量),输出如下:
library(dplyr) # Install the dplyr package if you don't already have it
dat2 = dat %.%
mutate(difficulty.scaled=difficulty - 1.5) %.%
group_by(X, Y) %.%
filter(abs(difficulty.scaled) < quantile(abs(difficulty.scaled), .5))
您提供的数据对 tnum difficulty X Y difficulty.scaled
1 trial2 1.4 1 male -0.1
2 trial4 1.5 1 female 0.0
3 trial6 1.2 2 male -0.3
4 trial8 1.6 2 female 0.1
5 trial10 1.4 3 male -0.1
6 trial12 1.5 3 female 0.0
7 trial14 1.2 4 male -0.3
8 trial16 1.6 4 female 0.1
和X
的每种组合都有相同数量的观察结果。如果您的实际数据在这些变量上不平衡,那么您可以选择特定数量的行,而不是选择每个子组中的行百分比。下面的代码选择每个子组中绝对值最低Y
的{{1}}行。这样,即使您的完整数据集不是,您的子集也会得到平衡(只要n
和difficulty.scaled
的每个组合至少有n
行数据。
X
Y
可确保返回准确的n=1
dat2 = dat %.%
mutate(difficulty.scaled=difficulty - 1.5) %.%
group_by(X, Y) %.%
filter(rank(abs(difficulty.scaled), ties.method="first") <= n)
行,即使有多个行具有相同的绝对值ties.method="first"
。
更新:如何将子集化数据划分为训练和测试集。
假设n
是您的平衡子集,您可以将其划分为训练和测试子集,如下所示:
difficulty.scaled
这将为每个子组返回10个随机采样的行。只需将此值设置为训练样本中每个子组的任意行数。请注意,您不需要按X和Y分组来创建训练样本。这是因为当您创建dat2
时,# Note that you need to use %>% instead of %.%
train = dat2 %>%
do(sample_n(., 10))
向dat2
添加了dplyr
继续识别的分组属性。请dat2
查看此内容。
dplyr
是一个通用函数,允许您对str(dat2)
内的数据帧执行任意操作。句点do
是一种&#34;代词&#34;表示数据框(在这种情况下为dplyr
)。这仅适用于.
而不是dat2
。 (%>%
处于正在开发阶段,正在从%.%
过渡到dplyr
以进行链接操作,因此从现在开始使用%.%
可能是最好的。)
%>%