【问题标题】:Select rows of data frame based on a vector with duplicated values根据具有重复值的向量选择数据框行
【发布时间】:2016-05-21 09:59:24
【问题描述】:

我想要的可以描述为:给一个数据框,包含所有的case-control对。在以下示例中,y 是案例-对照对的 id。我的数据集中有 3 对。我正在对 y 的不同值进行重新采样(这对将被选中或都不选中)。

sample_df = data.frame(x=1:6, y=c(1,1,2,2,3,3))
> sample_df
  x y
1 1 1
2 2 1
3 3 2
4 4 2
5 5 3
6 6 3
select_y = c(1,3,3)
select_y
> select_y
[1] 1 3 3

现在,我计算了一个向量,其中包含我要重新采样的对,即上面的select_y。这意味着第 1 号病例对照对将在我的新样本中,第 3 号也将在我的新样本中,但由于有两个 3,它将出现 2 次。所需的输出将是:

x y
1 1
2 1
5 3
6 3
5 3
6 3

除了写一个 for 循环之外,我找不到有效的方法......

解决方案: 基于@HubertL,经过一些修改,“矢量化”方法如下所示:

sel_y <- as.data.frame(table(select_y))
> sel_y
  select_y Freq
1        1    1
2        3    2
sub_sample_df = sample_df[sample_df$y%in%select_y,]
> sub_sample_df
  x y
1 1 1
2 2 1
5 5 3
6 6 3
match_freq = sel_y[match(sub_sample_df$y, sel_y$select_y),]
> match_freq
    select_y Freq
1          1    1
1.1        1    1
2          3    2
2.1        3    2
sub_sample_df$Freq = match_freq$Freq
rownames(sub_sample_df) = NULL
sub_sample_df
> sub_sample_df
  x y Freq
1 1 1    1
2 2 1    1
3 5 3    2
4 6 3    2
selected_rows = rep(1:nrow(sub_sample_df), sub_sample_df$Freq)
> selected_rows
[1] 1 2 3 3 4 4
sub_sample_df[selected_rows,]
    x y Freq
1   1 1    1
2   2 1    1
3   5 3    2
3.1 5 3    2
4   6 3    2
4.1 6 3    2

【问题讨论】:

    标签: r dataframe subset


    【解决方案1】:

    另一种不使用循环的方法:

    sample_df = data.frame(x=1:6, y=c(1,1,2,2,3,3))
    
    row_names <- split(1:nrow(sample_df),sample_df$y)
    
    select_y = c(1,3,3)
    
    row_num <- unlist(row_names[as.character(select_y)])
    
    ans <- sample_df[row_num,]
    

    【讨论】:

    • 我不得不说这是一个更好的解决方案。这是拆分的一个很好的用途。
    【解决方案2】:

    我找不到没有循环的方法,但至少它不是for循环,并且每个频率只有一次迭代:

    sample_df = data.frame(x=1:6, y=c(1,1,2,2,3,3))
    select_y = c(1,3,3)
    sel_y <- as.data.frame(table(select_y))
    do.call(rbind, 
            lapply(1:max(sel_y$Freq), 
                   function(freq) sample_df[sample_df$y %in% 
                                  sel_y[sel_y$Freq>=freq, "select_y"],]))
    
       x y
    1  1 1
    2  2 1
    5  5 3
    6  6 3
    51 5 3
    61 6 3
    

    【讨论】:

    • 是的,这与我现在正在做的类似。对于大型数据集,速度仍然值得关注。我在想一个更好的方法是创建一个 freq 变量,它代表该对的频率。例如,我可以先决定需要选择对 1 和 3,然后我决定需要选择 3 两次,然后 freq=rep(c(1,3), c(1,2)),类似于这个。而 sample_df[freq, ] 将完成这项工作。但是,我没有这样做的有效方法。
    • 根据你的提示,我想我想出了一个更好的。看上面。谢谢,团队合作。 @HubertL
    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    相关资源
    最近更新 更多