Скажем, у меня есть фрейм данных, например:
# Set RNG seed
set.seed(33550336)
# Create dummy data frame
df <- data.frame(PC1 = runif(20),
PC2 = runif(20),
PC3 = runif(20),
A = runif(20),
B = runif(20),
loc = sample(LETTERS[1:2], 20, replace = TRUE),
seas = sample(c("W", "S"), 20, replace = TRUE))
# > head(df)
# PC1 PC2 PC3 A B loc seas
# 1 0.8636470 0.02220823 0.7553348 0.4679607 0.0787467 A S
# 2 0.3522257 0.42733152 0.2412971 0.6691419 0.1194121 A W
# 3 0.5257408 0.44293320 0.3225228 0.0934192 0.2966507 B S
# 4 0.0667227 0.90273594 0.6297959 0.1962124 0.4894373 A W
# 5 0.3751383 0.50477920 0.6567203 0.4510632 0.4742191 B S
# 6 0.9197086 0.32024904 0.8382138 0.9907894 0.9335657 A S
Мне интересно вычислить корреляции между PC1
, PC2
и PC3
и каждой из переменных A
и B
сгруппированы по loc
и seas
.Так, например, основываясь на этом ответе , я мог бы сделать следующее:
# Correlation of variable A and PC1 per loc & seas combination
df %>%
group_by(loc, seas) %>%
summarise(cor = cor(PC1, A)) %>%
ungroup
# # A tibble: 4 x 3
# loc seas cor
# <fct> <fct> <dbl>
# 1 A S 0.458
# 2 A W 0.748
# 3 B S -0.0178
# 4 B W -0.450
Это дает мне то, что я хочу: соотношение между PC1
и A
для каждогокомбинация loc
и seas
. Высокий .
С чем я борюсь, это экстраполирую это для выполнения вычисления для каждой комбинации PC*
переменных и других переменных (например, A
и B
, в примере).Мой ожидаемый результат - таблица выше, но с колонкой для каждой комбинации для PC*
и других переменных.Я мог бы сделать эту длинную руку ... cor(PC2, A)
, cor(PC3, A)
, cor(PC1, B)
и т. Д., Но, вероятно, есть краткий способ кодирования вычисления.Я подозреваю, что это включает в себя do
, но я не могу полностью разобраться в этом ... Может кто-то просветить меня?
Решение
Я пошел с Дж. Гротендиком решение ниже , но для его перевода в нужный формат потребовалась некоторая реструктуризация.Я разместил код, который использовал здесь, на случай, если он будет полезен для других.
# Perform calculation
res <- by(df[1:5], df[-(1:5)], cor)
# Combinations of loc & seas
comb <- expand.grid(dimnames(res))
# loc seas
# 1 A S
# 2 B S
# 3 A W
# 4 B W
# A matrix corresponding to a loc & seas
# Plus the loc & seas themselves
restructure <- function(m, n){
# Convert to data frame
# Add rownames as column
# Retains PCs as rows, but not columns
# Gather variables to long format
# Unite PC & variable names
# Spread to a single row
# Add combination of loc & seas
m %>%
data.frame %>%
rownames_to_column() %>%
filter(grepl("PC", rownames(m))) %>%
select(-contains("PC")) %>%
gather(variable, value, -rowname) %>%
unite(comb, rowname, variable) %>%
spread(comb, value) %>%
bind_cols(n)
}
# Restructure each list element & combine into data frame
do.call(rbind, lapply(1:length(res), function(x)restructure(res[[x]], comb[x, ])))
, который дает,
# PC1_A PC1_B PC2_A PC2_B PC3_A PC3_B loc seas
# 1 0.45763159 -0.00925106 0.3522161 0.20916667 -0.2003091 0.3741403 A S
# 2 -0.01779813 -0.74328144 -0.3501188 0.46324158 0.8034240 0.4580262 B S
# 3 0.74835455 0.49639477 -0.3994917 -0.05233889 -0.5902400 0.3606690 A W
# 4 -0.45025181 -0.66721038 -0.9899521 -0.80989058 0.7606430 0.3738706 B W