2016-07-28 2 views
0

У меня такой большой df, как это (это только часть его). Для каждого образца (A, B, C. и т. Д. У меня их сто). У меня есть 3 значения (R, H и L).rowMeans со всеми столбцами, которые разделяют строку

IDs R.A R.B R.C H.A H.B H.C L.A L.B L.C 
A 6 5 4 5 5 5 5 1 4 
B 2 5 3 3 4 3 5 5 6 
C 6 6 3 2 2 1 4 1 3 
D 2 1 6 3 5 3 3 6 5 
E 4 1 3 2 3 1 4 4 4 
F 3 1 1 1 4 4 2 6 4 

Я хочу, чтобы создать новый ДФ с rowMeans для каждого образца, в этом примере:

IDs mean.A mean.B mean.C 
    A 3.0 5.0 3.0 
    B 5.7 5.3 4.7 
    C 3.0 4.7 4.7 
    D 3.0 1.7 5.3 
    E 3.3 4.0 4.3 
    F 4.0 2.3 4.0 

Я знаю, как это сделать для этого примера, но у меня есть сотни из них, и я не может это сделать, указав строку вручную (A, B, C).

newcols <- sapply(c("A$", "B$", "C$"), function(x) rowMeans(df[grep(x, names(df))])) 
setNames(cbind(df[1], newcols), c(names(df)[1], "mean.A", "mean.B", "mean.C")) 

Есть ли способ сделать операцию со всеми столбцами, которые разделяют «строку» без указания «строки»?

ответ

1

Поскольку у вас есть постоянный образец R.H. или L. следуют строки, представляющие интерес, использовать шаблон, чтобы извлечь все уникальные образцы, нужно смотреть через:

findThese <- unique(sub(pattern = "^[RHL]\\.(.+)$", 
         replacement = "\\1", 
         x = colnames(df)[!names(df) == "IDs"], # don't grab IDs column 
         perl = TRUE)) 

Затем используйте уникальные образцы, которые вы нашли (findThese) в вашем коде:

newcols <- sapply(paste0(findThese, "$"), function(x) rowMeans(df[grep(x, names(df))])) 
setNames(cbind(df[1], newcols), c(names(df)[1], paste0("mean", findThese))) 
# IDs mean.A mean.B mean.C 
#1 A 5.333333 3.666667 4.333333 
#2 B 3.333333 4.666667 4.000000 
#3 C 4.000000 3.000000 2.333333 
#4 D 2.666667 4.000000 4.666667 
#5 E 3.333333 2.666667 2.666667 
#6 F 2.000000 3.666667 3.000000 
5

Rename, так что у вас есть Group.[RHL], растопить в длинном формате, а затем aggregate:

names(dat) <- sub("^(.+)\\.(.+)$", "\\2.\\1", names(dat)) 
long <- reshape(dat, idvar="IDs", direction="long", sep=".", varying=-1, timevar=NULL) 
aggregate(. ~ IDs, data=long, FUN=mean) 

# IDs  A  B  C 
#1 A 5.333333 3.666667 4.333333 
#2 B 3.333333 4.666667 4.000000 
#3 C 4.000000 3.000000 2.333333 
#4 D 2.666667 4.000000 4.666667 
#5 E 3.333333 2.666667 2.666667 
#6 F 2.000000 3.666667 3.000000 

не должно быть трудно приспособить подобную логику dplyr или data.table - но я оставлю это для кого-то сегодня.

+1

@akrun - совсем нет - я вижу, что это очень чистое в data.table – thelatemail

1

Вот вариант с использованием data.table для melt набора данных в формат «длинный», как это имеет множественные measurepatterns, а затем получить mean на «ИД».

library(data.table) 
melt(setDT(df1), measure = patterns("A$", "B$", "C$"), 
    value.name = c("A", "B", "C"))[,lapply(.SD, mean) , IDs, .SDcols = A:C] 
# IDs  A  B  C 
#1: A 5.333333 3.666667 4.333333 
#2: B 3.333333 4.666667 4.000000 
#3: C 4.000000 3.000000 2.333333 
#4: D 2.666667 4.000000 4.666667 
#5: E 3.333333 2.666667 2.666667 
#6: F 2.000000 3.666667 3.000000