найти подмножество с помощью lapply / apply во фрейме данных

#r #lapply

#r #lapply

Вопрос:

У меня есть две ячейки фреймов данных и поддержка (показано ниже). Я хочу подмножество «ячейки», используя следующее условие: все строки «поддержки», которые поэлементно совпадают с вектором b. мой вывод будет состоять из всех этих строк «ячейки».

 a<-c(0,1,0)
b<-c(0,0,1)
level = c(3,2,4)
zero = c(1,2,1)


cell <- do.call(expand.grid, lapply(level, seq))    #create all cell
support <- t(apply(cell, 1, function(x)  (x != zero)))


> cell
   Var1 Var2 Var3
1     1    1    1
2     2    1    1
3     3    1    1
4     1    2    1
5     2    2    1
6     3    2    1
7     1    1    2
8     2    1    2
9     3    1    2
10    1    2    2
11    2    2    2
12    3    2    2
13    1    1    3
14    2    1    3
15    3    1    3
16    1    2    3
17    2    2    3
18    3    2    3
19    1    1    4
20    2    1    4
21    3    1    4
22    1    2    4
23    2    2    4
24    3    2    4
> support
      Var1 Var2 Var3
 [1,]    0    1    0
 [2,]    1    1    0
 [3,]    1    1    0
 [4,]    0    0    0
 [5,]    1    0    0
 [6,]    1    0    0
 [7,]    0    1    1
 [8,]    1    1    1
 [9,]    1    1    1
[10,]    0    0    1
[11,]    1    0    1
[12,]    1    0    1
[13,]    0    1    1
[14,]    1    1    1
[15,]    1    1    1
[16,]    0    0    1
[17,]    1    0    1
[18,]    1    0    1
[19,]    0    1    1
[20,]    1    1    1
[21,]    1    1    1
[22,]    0    0    1
[23,]    1    0    1
[24,]    1    0    1
> hD<-lapply(1:nrow(cell), function (x) cell[which(sum(support[x,]==b)==3),])
> do.call(rbind, hD)
  Var1 Var2 Var3
1    1    1    1
2    1    1    1
3    1    1    1
  

Я пытался использовать lapply, но я не получаю ожидаемого результата. Моим результатом должна быть строка 10,16 и 22 ячейки (показано ниже), поскольку строки 10,16 и 22 поддержки точно совпадают с вектором b. Я не хочу использовать какой-либо цикл.

   Var1 Var2 Var3
1    1    2    2
2    1    2    3
3    1    2    4

  

Ответ №1:

Вот еще один базовый вариант R

 subset(cell,Reduce(`amp;`,as.data.frame(t(t(support)==b))))
  

или

 subset(cell,Reduce(`amp;`,as.data.frame(support == t(replicate(nrow(support),b)))))
  

что дает

    Var1 Var2 Var3
10    1    2    2
16    1    2    3
22    1    2    4
  

Ответ №2:

Мы также можем сделать

 cell[!rowSums(support != b[col(support)]),]
#   Var1 Var2 Var3
#10    1    2    2
#16    1    2    3
#22    1    2    4
  

Комментарии:

1. yz<-1 level = 3 zero = 2 > H_D(level,zero,yz) Error in colSums(support == x) : 'x' must be an array of at least two dimensions Можете ли вы исправить эту ошибку? Это происходит, когда я использую colSums.

2. @Dihan Ошибка, похоже, связана со структурой объекта. У вас есть vector или data.frame/matrix . В примере я нахожу cell data.frame , что это так. Если это a vector , то вы можете получить такую ошибку. т.е. v1 <- 1:5; colSums(v1)#Error in colSums(v1) : 'x' must be an array of at least two dimensions

3. Это может быть вектор или фрейм данных. Это отлично работает для фрейма данных. Я пробовал drop=FALSE, но не работает!

4. @Dihan Как я уже сказал, если это a vector , оно не будет работать с rowSums or colSums . Вы можете создать проверку с помощью if(is.vector(cell))) do this else do that

Ответ №3:

Здесь apply логика, которая применима к обоим требованиям.

 cell[apply(support, 1, function(x) all(x == b)), ]
#    Var1 Var2 Var3
# 10    1    2    2
# 16    1    2    3
# 22    1    2    4

cell[apply(support, 1, function(x) all(x == b) | all(x == a)), ]
#    Var1 Var2 Var3
# 1     1    1    1
# 10    1    2    2
# 16    1    2    3
# 22    1    2    4
  

Ответ №4:

Вы можете сравнить b значения с каждой строкой support , транспонировав ее, и выбрать строки, в cell которых все значения совпадают.

 cell[colSums(t(support) == b) == length(b), ]

#   Var1 Var2 Var3
#10    1    2    2
#16    1    2    3
#22    1    2    4
  

Это также можно сделать с помощью sweep :

 cell[rowSums(sweep(support, 2, b, `==`)) == length(b), ]
  

Для сравнения с обоими a , и b мы можем сопоставить их по отдельности :

 cell[colSums(t(support) == b) == length(b) | 
     colSums(t(support) == a) == length(a), ]
  

Или использовать lapply :

 cell[Reduce(`|`, lapply(list(a, b), function(x) 
           colSums(t(support) == x) == length(x))), ]
  

Комментарии:

1. если я добавлю еще одно условие: все строки, которые совпадают с векторами a и b. a, совпадают со строкой 1. как вы добавите это условие в код?

2. @Dihan вы можете объединить два условия cell[colSums(t(support) == b) == length(b) | colSums(t(support) == a) == length(a), ] . Смотрите обновленный ответ.

3. yz<-1 level = 3 zero = 2 > H_D(level,zero,yz) Error in colSums(support == x) : 'x' must be an array of at least two dimensions Можете ли вы исправить эту ошибку? Это происходит, когда я использую colSums.

4. @Dihan Не должна ли длина level и zero быть такой же, как a и и b ? Как вы тогда будете сравнивать их оба?