Как усреднить столбцы с тем же именем и игнорировать столбцы, которые являются факторами - PullRequest
0 голосов
/ 23 января 2019

Я хотел бы усреднить данные из столбцов с тем же шаблоном имени.Некоторые из этих примеров прекрасно работают, если у вас есть только числовые данные:

Как рассчитать среднее значение для этих столбцов во фрейме данных с тем же именем столбца

Однако,У меня также есть столбец, который является фактором.Я могу удалить этот столбец, затем c (bind), чтобы вернуть его, но это кажется неуклюжим.Есть ли способ, которым я могу использовать что-то вроде !is.factor(x), чтобы игнорировать другой мой столбец?

df <- 
as.data.frame(matrix(c(1,3,3,2,2,5,3,2,3,6,3,2,4,7,3,2,5,4,5,2,6,3,5,2),
     ncol=6,
     dimnames=list(NULL, c("A.1", "B.1", "C.1", "B.2", "A.2", "C.2"))))

char = c("Apple", "banana", "cat", "rainbow")
df = cbind(char, df)

res <- as.data.frame(sapply(unique(names(df)), function(col) 
rowMeans(df[names(df) == col] )))

Ожидаемые результаты: res char A B C Apple 3.0 3 4.5 banana 3.5 6 4.5 cat 4.0 3 4.0 rainbow 2.0 2 2.0

Ошибка:

` Error in rowMeans(df[names(df) == col]) : 'x' must be numeric `

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Для базового решения R путем расширения того, что у вас есть,

df <- 
  as.data.frame(matrix(c(1,3,3,2,2,5,3,2,3,6,3,2,4,7,3,2,5,4,5,2,6,3,5,2),
                       ncol=6,
                       dimnames=list(NULL, c("A.1", "B.1", "C.1", "B.2", "A.2", "C.2"))))

char = c("Apple", "banana", "cat", "rainbow")
df <- cbind(char, df)

names(df) <- gsub('.\\d', '', grep('[a-zA-Z]', names(df), value = TRUE)) ## removes the digit from your groups

res <-
  data.frame(
    factor = df$char,
    sapply(setdiff(unique(names(df)), 'char'), function(col)
      rowMeans(df[, names(df) == col]))
  )

> res
   factor   A B   C
1   Apple 3.0 3 4.5
2  banana 3.5 6 4.5
3     cat 4.0 3 4.0
4 rainbow 2.0 2 2.0
0 голосов
/ 23 января 2019

в базе R: вы ищете следующее:

aggregate(.~char, reshape(df, 2:ncol(df), idvar = 'char',dir = 'long'), mean)[-2]

     char   A B   C
1   Apple 3.0 3 4.5
2  banana 3.5 6 4.5
3     cat 4.0 3 4.0
4 rainbow 2.0 2 2.0

library(datatable)
melt(setDT(df),'char',patterns(A='^A',B='^B',C='^C'))[,-2][,lapply(.SD,mean),by=char]
        char   A B   C
1:   Apple 3.0 3 4.5
2:  banana 3.5 6 4.5
3:     cat 4.0 3 4.0
4: rainbow 2.0 2 2.0
0 голосов
/ 23 января 2019

Используя tidyverse, я придумал следующую операцию с конвейером

##Recreate the data
df <- as.data.frame(matrix(c(1,3,3,2,2,5,3,2,3,6,3,2,4,7,3,2,5,4,5,2,6,3,5,2),
                   ncol=6,
                   dimnames=list(NULL, c("A.1", "B.1", "C.1", "B.2", "A.2", "C.2"))))

char = c("Apple", "banana", "cat", "rainbow")
df = cbind(char, df)

##Load tidyverse

library(tidyverse)

#Gather the columns with titles, extract the first letter, then summarize
 new_df <- df %>% gather(column_type, value, `A.1`:`C.2`) %>%
           mutate(initial = str_extract(column_type, "[A-Z]")) %>%
           group_by(initial, char) %>% 
           summarise(mean = mean(value)) %>%
           spread(initial, mean)

new_df
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...