У меня есть следующий фрейм данных.
temp = structure(list(A = c(0, 0, 0, 3.72900887033786, 1.94860084749336,
0), C = c(0, 0, 0, 3.44095219802964, 2.35049724708413, 0.0285691521967709
), A = c(0, 0, 0, 3.29572302453997, 0.933572638261024, 0), D = c(0,
0, 0, 2.4905701304462, 1.54101915313356, 0), E = c(0, 0, 0, 4.23189316164533,
1.7311832415722, 0), E = c(0, 0, 0, 4.37851162325373, 2.50080205305716,
0), D = c(0, 0, 0, 3.68929916053589, 2.4905701304462, 0.189033824390017
), F = c(0, 2.27500704749987, 0, 3.68032435684402, 1.77820857639809,
0), A = c(0, 0, 0, 3.5668151540109, 1.72683121703249, 0.0285691521967709
), G = c(0, 0, 0, 5.6450098843911, 3.09929520433778, 0)), row.names = c("5_8S_rRNA",
"5S_rRNA", "7SK", "A1BG", "A1BG-AS1", "A1CF"), class = "data.frame")
Похоже на это.
A C A D E E D F A G
5_8S_rRNA 0.000000 0.00000000 0.0000000 0.000000 0.000000 0.000000 0.0000000 0.000000 0.00000000 0.000000
5S_rRNA 0.000000 0.00000000 0.0000000 0.000000 0.000000 0.000000 0.0000000 2.275007 0.00000000 0.000000
7SK 0.000000 0.00000000 0.0000000 0.000000 0.000000 0.000000 0.0000000 0.000000 0.00000000 0.000000
A1BG 3.729009 3.44095220 3.2957230 2.490570 4.231893 4.378512 3.6892992 3.680324 3.56681515 5.645010
A1BG-AS1 1.948601 2.35049725 0.9335726 1.541019 1.731183 2.500802 2.4905701 1.778209 1.72683122 3.099295
A1CF 0.000000 0.02856915 0.0000000 0.000000 0.000000 0.000000 0.1890338 0.000000 0.02856915 0.000000
Что я хотел бы сделать, так это свернуть любой столбец, который является дубликатом, путем усреднения дубликатов, но я хочу сделать это для каждой строки.
Идеальный фрейм данных будет содержать такое же количество строк, но будет содержать только столбцы A, C, D, E, F, G. Возможно ли это?
Мы могли бы использовать split.default
для разделения по именам столбцов и зацикливания на list
, применить rowMeans
sapply(split.default(temp, names(temp)), rowMeans)
A C D E F G
5_8S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
5S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 2.275007 0.000000
7SK 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
A1BG 3.530515683 3.44095220 3.08993465 4.305202 3.680324 5.645010
A1BG-AS1 1.536334901 2.35049725 2.01579464 2.115993 1.778209 3.099295
A1CF 0.009523051 0.02856915 0.09451691 0.000000 0.000000 0.000000
Это то, что вы ищете?
library(tidyr)
library(dplyr)
output <- temp %>%
add_rownames(var = "ID") %>%
pivot_longer(-ID) %>%
mutate(name = gsub("\\.*\\d*", "", name)) %>%
group_by(ID, name) %>%
summarise(value = mean(value)) %>%
mutate(name = gsub("\\.*\\d*", "", name)) %>%
pivot_wider(names_from = "name", values_from = "value")
output
# A tibble: 6 × 7
# Groups: ID [6]
ID A C D E F G
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 5_8S_rRNA 0 0 0 0 0 0
2 5S_rRNA 0 0 0 0 2.28 0
3 7SK 0 0 0 0 0 0
4 A1BG 3.53 3.44 3.09 4.31 3.68 5.65
5 A1BG-AS1 1.54 2.35 2.02 2.12 1.78 3.10
6 A1CF 0.00952 0.0286 0.0945 0 0 0
Вот базовое решение R:
t(do.call(rbind, by(t(temp), row.names(t(temp)), FUN = colMeans)))
Или с tidyverse
Вот вариант tidyverse
, где мы можем разделить уникальные имена, затем мы устанавливаем имена для каждого кадра данных, а затем используем rowMeans
. Однако мы должны использовать setNames
в первом выражении map
, чтобы сделать имена столбцов уникальными, поскольку tidyverse
не любит повторяющиеся имена столбцов. Затем, поскольку имена строк также удаляются, мы можем добавить их обратно в конце.
library(tidyverse)
map(.x = unique(names(temp)), ~
select(setNames(temp, make.names(names(temp), unique = TRUE)), starts_with(.x))) %>%
set_names(unique(names(temp))) %>%
map_dfc(., rowMeans) %>%
as.data.frame() %>%
`rownames<-`(row.names(temp))
Или другое базовое решение R:
temp2 <- t(temp)
t(tapply(temp2, list(row.names(temp2)[row(temp2)], colnames(temp2)[col(temp2)]), FUN = mean))
Вывод
A C D E F G
5_8S_rRNA 0.00000000 0.0000000 0.0000000 0.00000 0.00000 0.00000
5S_rRNA 0.00000000 0.0000000 0.0000000 0.00000 2.27501 0.00000
7SK 0.00000000 0.0000000 0.0000000 0.00000 0.00000 0.00000
A1BG 3.53051568 3.4409522 3.0899346 4.30520 3.68032 5.64501
A1BG-AS1 1.53633490 2.3504972 2.0157946 2.11599 1.77821 3.09930
A1CF 0.00952305 0.0285692 0.0945169 0.00000 0.00000 0.00000
Другое базовое решение R с rowsum
:
t(rowsum(t(temp), names(temp)) / c(table(names(temp))))
A C D E F G
5_8S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
5S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 2.275007 0.000000
7SK 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
A1BG 3.530515683 3.44095220 3.08993465 4.305202 3.680324 5.645010
A1BG-AS1 1.536334901 2.35049725 2.01579464 2.115993 1.778209 3.099295
A1CF 0.009523051 0.02856915 0.09451691 0.000000 0.000000 0.000000
Использование data.table
library('data.table')
d <- transpose(as.data.table(temp), keep.names = "rn")
d <- d[, by = rn, lapply(.SD, mean)]
d <- cbind(rn = row.names(temp), transpose(d, make.names = T))
Вариант dplyr
+ tidyr
с использованием pivot_*
library(dplyr)
library(tidyr)
temp %>%
cbind(rmn = rownames(temp)) %>%
pivot_longer(!rmn) %>%
group_by(rmn, name) %>%
summarise(value = mean(value), .groups = "drop") %>%
pivot_wider(names_from = name) %>%
column_to_rownames("rmn")
дает
A C D E F G
5_8S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
5S_rRNA 0.000000000 0.00000000 0.00000000 0.000000 2.275007 0.000000
7SK 0.000000000 0.00000000 0.00000000 0.000000 0.000000 0.000000
A1BG 3.530515683 3.44095220 3.08993465 4.305202 3.680324 5.645010
A1BG-AS1 1.536334901 2.35049725 2.01579464 2.115993 1.778209 3.099295
A1CF 0.009523051 0.02856915 0.09451691 0.000000 0.000000 0.000000
Или мы можем использовать xtabs
немного
temp %>%
cbind(rmn = rownames(temp)) %>%
pivot_longer(!rmn) %>%
group_by(rmn, name) %>%
summarise(value = mean(value), .groups = "drop") %>%
xtabs(value ~ ., .)
что дает
name
rmn A C D E F
5_8S_rRNA 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000
5S_rRNA 0.000000000 0.000000000 0.000000000 0.000000000 2.275007047
7SK 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000
A1BG 3.530515683 3.440952198 3.089934645 4.305202392 3.680324357
A1BG-AS1 1.536334901 2.350497247 2.015794642 2.115992647 1.778208576
A1CF 0.009523051 0.028569152 0.094516912 0.000000000 0.000000000
name
rmn G
5_8S_rRNA 0.000000000
5S_rRNA 0.000000000
7SK 0.000000000
A1BG 5.645009884
A1BG-AS1 3.099295204
A1CF 0.000000000