2016-08-09 4 views
-2

Я хочу рассчитать среднее значение и sd для частот по группам в R. Вот мои данные:Частота по группам

  Opinion 1 2 3 4 5 6 7 8 9 10 11 
     Group 
     A   0 1 1 0 3 15 8 9 12 5 3 
     B   1 3 5 8 15 18 17 14 15 9 4 
     C   8 4 15 19 14 25 17 16 20 4 6 
     D   0 0 0 0 0 0 1 0 0 0 0 
     E   0 6 5 8 12 14 15 15 14 7 8 
     F   1 0 0 0 1 1 0 1 1 0 0 
     G   3 0 4 4 1 1 1 1 1 0 1 

То, что я хочу, чтобы вычислить это среднее и сд для каждой группы (A, B, C, D, F, G). Каждая ячейка является частотой. В частности, это ряд ответов, которые каждое «мнение» было получено от респондентов. Например, респонденты, которые являются сторонниками группы А, в среднем отвечают мнением 7.5 и sd 1.9.

Я рассчитываю вручную и sd для каждой группы. Как написать цикл, который может вычислить это сразу? Я уверен, что кто-то здесь уже это знает. Я бы очень признателен вам за вашу помощь. Спасибо.

P.S. apply() не будет работать, потому что мне нужно среднее и sd частот.

+0

'применяются (данные, 1, среднее значение) и' применяются (данные, 1, SD) '1 обозначает первый размерности обхода, он же строк. – FisherDisinformation

+0

Возможный дубликат [r получает значение n столбцов по строке] (http: // stackoverflow.com/questions/31683217/r-get-mean-of-n-columns-by-row) – dash2

+0

@ dash2 Это не так просто. Здесь важна позиция значений в рядах. Поэтому 'rowMeans' или' apply (data, 1, mean) 'не даст правильный результат. – RHertel

ответ

1

Для вычисления среднего значения каждой группы вы можете использовать следующий код:

the_means <- setNames(rowSums(col(df1)*df1)/rowSums(df1), 
         LETTERS[seq_len(nrow(df1))]) 
#> the_means 
#  A  B  C  D  E  F  G 
#7.526316 6.761468 6.013514 7.000000 6.846154 5.800000 4.529412 

данные:

df1 <- structure(list(V1 = c(0L, 1L, 8L, 0L, 0L, 1L, 3L), V2 = c(1L, 3L, 
4L, 0L, 6L, 0L, 0L), V3 = c(1L, 5L, 15L, 0L, 5L, 0L, 4L), V4 = c(0L, 8L, 
19L, 0L, 8L, 0L, 4L), V5 = c(3L, 15L, 14L, 0L, 12L, 1L, 1L), V6 = c(15L, 
18L, 25L, 0L, 14L, 1L, 1L), V7 = c(8L, 17L, 17L, 1L, 15L, 0L, 1L), 
V8 = c(9L, 14L, 16L, 0L, 15L, 1L, 1L), V9 = c(12L, 15L, 20L, 0L, 14L, 1L, 
1L), V10 = c(5L, 9L, 4L, 0L, 7L, 0L, 0L), V11 = c(3L, 4L, 6L, 0L, 8L, 0L, 
1L)), .Names = c("V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", 
"V10", "V11"), class = "data.frame", row.names = c(NA, -7L)) 
+0

Вы планировали ответить на вторую часть вопроса? – Frank

+0

@Frank Я попытался, но я сдался после некоторого времени, так как я не нашел элегантного решения. Если у вас его есть, продолжайте ... – RHertel

+0

Нет, ничего не получилось, кроме установки пакета с функциями с именем rowMeans и rowSds, или, может быть, очень неэффективным вариантом, например 'lapply (split (m, row (m)), summary)' , О, не прочь просто прочитать свой комментарий выше и фактический вопрос, и я вижу, что это сложно. – Frank

1

Для средств (с помощью @ прекрасных, воспроизводимых данных RHertel в)

apply(df1, 1, function(x) weighted.mean(1:11, w = x)) 
# [1] 7.526316 6.761468 6.013514 7.000000 6.846154 5.800000 4.529412 

Для стандартных отклонений:

apply(df1, 1, function(x) sqrt(weighted.mean((1:11)^2, w = x) - weighted.mean(1:11, w = x)^2)) 
# [1] 1.883495 2.254045 2.552123 0.000000 2.448584 2.785678 2.767833 

Мы используем определение Var(X) = E(X^2) - E(X)^2 и извлечь квадратный корень, что для стандартного отклонения. Если вы хотите стандартное отклонение выборки, вы можете умножить на sqrt(rowSums(df1)/(rowSums(df1) - 1)). Это, конечно же, приведет к NA или NaN для группы D только с одним наблюдением.

Чтобы сделать это более общим, вы можете заменить биты 1:11 на as.numeric(colnames(df1)) или что-то подходящее. Трудно сказать, какая у вас структура данных, возможно, table?

+0

Ницца! Возможно, более общий способ может заключаться в замене '1: 11' на' seq_len (ncol (df1)) '. – RHertel

+0

Я скептически отношусь к какому-либо файлу data.frame - моя догадка - это объект таблицы. И тогда мне нравится предложение 'as.numeric (colnames()), поскольку оно должно работать даже для несекретных, не-1-начальных столбцов (например,' df1 = table (am = mtcars $ am, cyl = mtcars $ цил) '). И я также с удовольствием оставил эти трюки конечному пользователю. – Gregor

+0

справедливо! :) – RHertel

1

Я также хотел бы опубликовать свое решение.

То, что я сделал это:

  1. создал data.frame() из table()

    b1 <- data.frame(table(data$Group, as.numeric(data$Opinion))) 
    
  2. Expanded данные из частот векторов (в противном случае R продолжал показывать то, что я хотел бы получить, если бы я использовал apply())

    b2 <- b[rep(row.names(b), b$Freq), 1:2] 
    
  3. Б петлю из ddply()

    b3 <- ddply(b2, .(Var1), summarize, mean = mean(as.numeric(Var2), na.rm = TRUE), sd = sd(Var2)) 
    

 Смежные вопросы

  • Нет связанных вопросов^_^