перестановка df по строкам с условиями в пределах значений столбцов - PullRequest
0 голосов
/ 13 марта 2019

Предположим, у меня есть 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 есть «c1» в cond2, следующая строка не должна содержать «c1» , но "с2" или "с3".

1 Ответ

2 голосов
/ 13 марта 2019

Вы можете взять образец, например в два раза длиннее 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...