【问题标题】:permuting a df by rows with conditions within columns' values用列值内的条件按行排列 df
【发布时间】:2019-03-13 17:15:22
【问题描述】:

假设我有一个像这样的 df

df1 <- data.frame(n =c("n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10", "n11", "n12", "n13", "n14", "n15", "n16", "n17", "n18"), Cond1 =c("I1", "I2", "I3", "I4", "I5", "I6", "I1", "I2", "I3", "I4", "I5", "I6", "I1", "I2", "I3", "I4", "I5", "I6"), Cond2 =c("c1", "c1","c1","c1","c1","c1","c2", "c2","c2","c2","c2","c2","c3","c3","c3","c3","c3","c3"))
df1

我按行采样

df2 <- df1[sample(nrow(df1)),]
df2

我想设置采样条件,例如,在 Cond2 列中,“c1”在下一行再次出现之前有一个列表的间隙。

因此,我想要行的随机顺序,但访问列的值,如果在新 df 的前一行中 cond2 中有“c1”,则下一行不能包含“c1” ,但“c2”或“c3”。

【问题讨论】:

    标签: r dataframe permutation


    【解决方案1】:

    您可以取样,例如两倍于df1。然后利用Cond2 列中的数字设置差异并删除差异为0 的所有行。最后将数据框收缩到df1的长度。

    df2 <- df1[sample(nrow(df1), nrow(df1)*2, replace=TRUE), ]
    df2$tmp <- diff(c(0, as.numeric(gsub("\\D", "", df2$Cond2))))
    df2[df2$tmp != 0, -4][1:nrow(df1), ]
    #        n Cond1 Cond2
    # 2     n2    I2    c1
    # 8     n8    I2    c2
    # 4     n4    I4    c1
    # 12   n12    I6    c2
    # 3.1   n3    I3    c1
    # 13   n13    I1    c3
    # 11   n11    I5    c2
    # 5     n5    I5    c1
    # 11.1 n11    I5    c2
    # 14   n14    I2    c3
    # 1     n1    I1    c1
    # 18   n18    I6    c3
    # 3.2   n3    I3    c1
    # 8.1   n8    I2    c2
    # 13.2 n13    I1    c3
    # 10.1 n10    I4    c2
    # 15   n15    I3    c3
    # 1.1   n1    I1    c1
    

    要使解决方案适应多列,您可以使用while 循环,因为它是一个长度未知的迭代过程,直到所有差异都为0

    set.seed(42)  # for sake of reproducibility
    df2 <- df1[sample(nrow(df1), nrow(df1)*2, replace=TRUE), ]
    
    df2$tmp1 <- diff(c(0, as.numeric(gsub("\\D", "", df2$Cond1))))
    df2$tmp2 <- diff(c(0, as.numeric(gsub("\\D", "", df2$Cond2))))
    
    while (any(df2[4:5] == 0)) {
      df2 <- df2[df2$tmp1 != 0, ]
      df2 <- df2[df2$tmp2 != 0, ]
      df2$tmp1 <- diff(c(0, as.numeric(gsub("\\D", "", df2$Cond1))))
      df2$tmp2 <- diff(c(0, as.numeric(gsub("\\D", "", df2$Cond2))))
    }
    
    df2
    #        n Cond1 Cond2 tmp1 tmp2
    # 17   n17    I5    c3    5    3
    # 6     n6    I6    c1    1   -2
    # 15   n15    I3    c3   -3    2
    # 12   n12    I6    c2    3   -1
    # 14   n14    I2    c3   -4    1
    # 3     n3    I3    c1    1   -2
    # 12.1 n12    I6    c2    3    1
    # 13   n13    I1    c3   -5    1
    # 9     n9    I3    c2    2   -1
    # 13.1 n13    I1    c3   -2    1
    # 9.1   n9    I3    c2    2   -1
    # 17.3 n17    I5    c3    2    1
    # 3.1   n3    I3    c1   -2   -2
    # 18.1 n18    I6    c3    3    2
    # 2     n2    I2    c1   -4   -2
    # 10.1 n10    I4    c2    2    1
    # 17.5 n17    I5    c3    1    1
    # 9.3   n9    I3    c2   -2   -1
    # 16   n16    I4    c3    1    1
    # 7     n7    I1    c2   -3   -1
    # 15.2 n15    I3    c3    2    1
    

    【讨论】:

    • 谢谢,这似乎有效!如果我还想在逻辑上组合限制,例如为 Cond1 和 Cond2 设置约束,该怎么办?我想确定两列中重复间隙的长度?所以我尝试它是否可以计算 Cond1 和 Cond2 的值在两个相邻行中从不重复的行的顺序,例如 1 或 2 行。
    • @Mary 我已经将解决​​方案扩展为没有像您最初要求的那样重复的两列。请考虑将mark the question as answeredupvote it 作为我所花费时间的奖励。
    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多