Как создать новую строку на основе всех ячеек в существующем R-кадре данных - PullRequest
1 голос
/ 23 марта 2019

Я хочу создать новую строку на основе всех других ячеек в существующем R-кадре данных.Вот существующий R-фрейм данных с именем "dat1".

dat1 <- structure(list(a = c(0.80, -0.72, 1.36, 1.57, -0.58), 
                       b = c(-1.39, 0.66, -0.01, 1.24, 1.19), 
                       c = c(0.35, 0.44, 0.32, 1.90, -0.11), 
                       d = c(-0.09, -1.26, 1.14, -0.37, 0.95), 
                       e = c(0.59, 0.05,-1.08, 1.44, 0.58), 
                       weight = c(3.2, 4.3, 5.6, 3.4, 5.2)), 
                   row.names = c(NA, -5L), class = "data.frame")

«данные» содержат пять строк и пять столбцов.Я хочу создать шестую строку.

data[6,1] = data[1,1]*data[1,6]+data[2,1]*data[2,6]+data[3,1]*data[3,6]+data[4,1]*data[4,6]+data[5,1]*data[5,6]
data[6,2] = data[1,2]*data[1,6]+data[2,2]*data[2,6]+data[3,2]*data[3,6]+data[4,2]*data[4,6]+data[5,2]*data[5,6]
data[6,3] = data[1,3]*data[1,6]+data[2,3]*data[2,6]+data[3,3]*data[3,6]+data[4,3]*data[4,6]+data[5,3]*data[5,6]
data[6,4] = data[1,4]*data[1,6]+data[2,4]*data[2,6]+data[3,4]*data[3,6]+data[4,4]*data[4,6]+data[5,4]*data[5,6]
data[6,5] = data[1,5]*data[1,6]+data[2,5]*data[2,6]+data[3,5]*data[3,6]+data[4,5]*data[4,6]+data[5,5]*data[5,6]code here
data[6,6] = NA

Вот что я пробовал:

Метод 1

data[6,1] <- data[1,1]*data[1,6]+data[2,1]*data[2,6]+data[3,1]*data[3,6]+data[4,1]*data[4,6]+data[5,1]*data[5,6]
data[6,2] <- data[1,2]*data[1,6]+data[2,2]*data[2,6]+data[3,2]*data[3,6]+data[4,2]*data[4,6]+data[5,2]*data[5,6]
data[6,3] <- data[1,3]*data[1,6]+data[2,3]*data[2,6]+data[3,3]*data[3,6]+data[4,3]*data[4,6]+data[5,3]*data[5,6]
data[6,4] <- data[1,4]*data[1,6]+data[2,4]*data[2,6]+data[3,4]*data[3,6]+data[4,4]*data[4,6]+data[5,4]*data[5,6]
data[6,5] <- data[1,5]*data[1,6]+data[2,5]*data[2,6]+data[3,5]*data[3,6]+data[4,5]*data[4,6]+data[5,5]*data[5,6]
data[6,6] <- NA

Я также пытался метод 2:

data1 <- data[1:5,1:5]

Затем создайте новый фрейм данных с именем data2:

for (i in 1:5) {
  for (j in 1:5) {
    data2[i, j] <- data1[i, j] * data[j, 6]
  }
}

Затем создайте новую строку

newrow <- colSums(data2)

Затем окончательные данные3

data3 <- rbind(data1,newrow)

Я обнаружил, что результаты были разными для метода 1 и 2. Поскольку мой истинный набор данных намного больше, чем «данные».Я надеюсь, что кто-то может помочь мне с простым способом вычислить новый ряд.

Заранее спасибо.

1 Ответ

0 голосов
/ 23 марта 2019

Причина, по которой вы получаете разные результаты, заключается в том, что вы перепутали индексы в своем for -цикле Вы хотите рассчитать взвешенную сумму для каждого столбца. Таким образом, вы должны перебрать столбцы, а затем умножить каждый столбец на соответствующий вес. В вашем for -цикле вы указываете неправильные веса. Вы умножаете столбец j всегда на вес строки j. Вот как вы можете это исправить (полностью воспроизводимым способом):

Первые результаты для Метод 1 :

method1 <- dat1

method1[6,1] <- method1[1,1]*method1[1,6]+method1[2,1]*method1[2,6]+method1[3,1]*method1[3,6]+method1[4,1]*method1[4,6]+method1[5,1]*method1[5,6]
method1[6,2] <- method1[1,2]*method1[1,6]+method1[2,2]*method1[2,6]+method1[3,2]*method1[3,6]+method1[4,2]*method1[4,6]+method1[5,2]*method1[5,6]
method1[6,3] <- method1[1,3]*method1[1,6]+method1[2,3]*method1[2,6]+method1[3,3]*method1[3,6]+method1[4,3]*method1[4,6]+method1[5,3]*method1[5,6]
method1[6,4] <- method1[1,4]*method1[1,6]+method1[2,4]*method1[2,6]+method1[3,4]*method1[3,6]+method1[4,4]*method1[4,6]+method1[5,4]*method1[5,6]
method1[6,5] <- method1[1,5]*method1[1,6]+method1[2,5]*method1[2,6]+method1[3,5]*method1[3,6]+method1[4,5]*method1[4,6]+method1[5,5]*method1[5,6]
method1[6,6] <- NA

method1
#        a      b      c     d      e weight
# 1  0.800 -1.390  0.350 -0.09  0.590    3.2
# 2 -0.720  0.660  0.440 -1.26  0.050    4.3
# 3  1.360 -0.010  0.320  1.14 -1.080    5.6
# 4  1.570  1.240  1.900 -0.37  1.440    3.4
# 5 -0.580  1.190 -0.110  0.95  0.580    5.2
# 6  9.402  8.738 10.692  4.36  3.967     NA

Вот модифицированный Метод 2 :

data1 <- dat1[1:5, 1:5]
data2 <- data.frame(matrix(numeric(5*5), ncol = 5))
names(data2) <- letters[1:5]

for (i in 1:5) {
  for (j in 1:5) {
    data2[j, i] <- data1[j, i] * dat1[j, 6]
  }
}

method2 <- rbind(data1, colSums(data2))

method2 
#        a      b      c     d      e
# 1  0.800 -1.390  0.350 -0.09  0.590
# 2 -0.720  0.660  0.440 -1.26  0.050
# 3  1.360 -0.010  0.320  1.14 -1.080
# 4  1.570  1.240  1.900 -0.37  1.440
# 5 -0.580  1.190 -0.110  0.95  0.580
# 6  9.402  8.738 10.692  4.36  3.967

Хорошо, теперь результаты совпадают. Я предлагаю другой способ, Метод 3 :

dat1[6, ] <- c(apply(dat1[, 1:5], MARGIN = 2, function(x) sum(x * dat1[, 6])), NA)

dat1
#        a      b      c     d      e weight
# 1  0.800 -1.390  0.350 -0.09  0.590    3.2
# 2 -0.720  0.660  0.440 -1.26  0.050    4.3
# 3  1.360 -0.010  0.320  1.14 -1.080    5.6
# 4  1.570  1.240  1.900 -0.37  1.440    3.4
# 5 -0.580  1.190 -0.110  0.95  0.580    5.2
# 6  9.402  8.738 10.692  4.36  3.967     NA

Как это работает? apply применяет функцию, указанную для всех столбцов (MARGIN = 2) данных dat1[, 1:5]. Функция рассчитывает произведение определенного столбца (x) и весов, сохраненных в dat1[, 6], и суммирует числа. В конце нам нужно добавить NA, поскольку в dat1 есть шесть столбцов, а apply возвращает только вектор из пяти значений.

Данные

dat1 <- structure(list(a = c(0.80, -0.72, 1.36, 1.57, -0.58), 
                       b = c(-1.39, 0.66, -0.01, 1.24, 1.19), 
                       c = c(0.35, 0.44, 0.32, 1.90, -0.11), 
                       d = c(-0.09, -1.26, 1.14, -0.37, 0.95), 
                       e = c(0.59, 0.05,-1.08, 1.44, 0.58), 
                       weight = c(3.2, 4.3, 5.6, 3.4, 5.2)), 
                  row.names = c(NA, -5L), class = "data.frame")
...