R: Суммировать ячейки по строке фрейма данных A, если соответствующая ячейка в фрейме данных B равна некоторому значению

#r

#r

Вопрос:

Фрейм данных A:

 Tree  Apple Orange  Pear
1     0     0       1
0     0     1       1
1     1     0       1
1     0     0       0
  

Фрейм данных B:

 WK1   WK2   WK3   WK4
1     2     3     8
3     4     2     1
1     3     2     5
6     2     5     8
  

Оба фрейма данных A и B имеют одинаковые размеры. Что я пытаюсь сделать, так это суммировать ячейки по строкам в фрейме данных B, только если соответствующая ячейка в фрейме данных A равна единице.

Ожидаемый результат:

 WK1   WK2   WK3   WK4   SUM
1     2     3     8     9
3     4     2     1     3
1     3     2     5     4
6     2     5     8     6
  

Поскольку (строка 1, столбец 1) и (строка 1, столбец 4) фрейма данных A равны единице, то (строка 1, столбец 1) и (строка 1, столбец 4) фрейма данных B суммируются. Не сокращенная форма фреймов данных A и B содержит более 883 столбцов и 12000 строк, поэтому я не могу написать имя каждого столбца.

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

1. Сумма третьего элемента должна быть больше 4, потому что у вас есть 1 в дереве, яблоке и груше

Ответ №1:

Поскольку A фрейм данных имеет значение 1/0, и вы можете умножить A фрейм данных на B и вычислить сумму по строке.

 B$SUM <- rowSums(A * B)
B

#  WK1 WK2 WK3 WK4 SUM
#1   1   2   3   8   9
#2   3   4   2   1   3
#3   1   3   2   5   9
#4   6   2   5   8   6
  

Если у вас могут быть значения, отличные от 0 и 1, A вы можете сравнить A с 1, а затем умножить.

 B$SUM <- rowSums( (A == 1) * B)
  

Ответ №2:

Можно умножить на наборы данных, чтобы 0 остались 0, а 1 был заменен значением второго набора данных, и, поскольку они есть NA , мы можем использовать na.rm в rowSums

 df2$SUM <- rowSums((df1 == 1) * df2, na.rm = TRUE)
df2
#  WK1 WK2 WK3 WK4 SUM
#1   1   2   3   8   9
#2   3   4   2   1   3
#3   1   3   2   5   9
#4   6   2   5   8   6
  

Или другой вариант Map/Reduce

 df2$SUM <- Reduce(` `, Map(`*`, df1, df2))
  

Или мы можем replace элементы в ‘df2’, где ‘df1’ равно 0, NA и использовать rowSums для создания столбца ‘SUM’ в base R

 df2$SUM <- rowSums(replace(df2, df1 ==0, NA), na.rm = TRUE)
  

Или немного более компактный вариант

 df2$SUM <- rowSums(df2 *NA^(df1== 0), na.rm = TRUE)
  

ПРИМЕЧАНИЕ: Это также будет работать при наличии недвоичных элементов

данные

 df1 <- structure(list(Tree = c(1L, 0L, 1L, 1L), Apple = c(0L, 0L, 1L, 
0L), Orange = c(0L, 1L, 0L, 0L), Pear = c(1L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA, 
-4L))

df2 <- structure(list(WK1 = c(1L, 3L, 1L, 6L), WK2 = c(2L, 4L, 3L, 2L
), WK3 = c(3L, 2L, 2L, 5L), WK4 = c(8L, 1L, 5L, 8L)), class = "data.frame", 
row.names = c(NA, 
-4L))