以下は例です。
df1 <- data.frame("names" = c('John','Peter','Jolie'), "value1" = c(21, 24, 26), "value2" = c(20, 23, 32))
df2 <- data.frame("names" = c('Sam','John','Jolie'), "value1" = c(35, 11, 10), "value2" = c(10, 28, 27))
df3 <- data.frame("names" = c('Louis','Jolie','John'), "value1" = c(42, 74, 26), "value2" = c(26, 53, 54))
df4 <- data.frame("names" = c('Ale','John','Jolie'), "value1" = c(61, 34, 76), "value2" = c(28, 63, 38))
df5 <- data.frame("names" = c('John','Jolie','peter'), "value1" = c(11, 84, 86), "value2" = c(50, 13, 68))
intersect_names <- Reduce(intersect, list(df1$names,df2$names,df3$names,df4$names,df5$names))
reduce コマンドと intersect コマンドを使用すると、すべての名前の交差部分を取得できます。ただし、データフレーム内の各名前の value1 と value2 の対応する平均が必要です。
期待される出力データフレーム:
names Value1 Value2
John 20.6 43
Jolie 54 32.6
例: 値 20.6 は、mean(c(21,11,26,34,11)) を取得することによって取得されました。
------------------------
データフレームのリストを作成し、intersect_names の行を抽出し、各名前の平均を取得します。
list_df <- mget(paste0('df', 1:5))
intersect_names <- Reduce(intersect, lapply(list_df, `[[`, 'names'))
aggregate(.~names, do.call(rbind, lapply(list_df, function(x)
x[x$names %in% intersect_names, ])), mean)
tidyverse 関数を使用した場合も同様です:
library(dplyr)
library(purrr)
map_df(list_df, ~.x %>% filter(names %in% intersect_names)) %>%
group_by(names) %>%
summarise(across(.fns = mean))
# names value1 value2
# <chr> <dbl> <dbl>
#1 John 20.6 43
#2 Jolie 54 32.6
2
この解決策は、私が尋ねた問題に対してうまく機能します。ただし、値の一部が負であり、絶対値を考慮して平均をとりたい場合は、コードを変更するにはどうすればよいですか?何か提案はありますか?
– ボットロギー
2020 年 9 月 5 日 6:08
1
匿名関数を集合的に使用できます。集約(.~names、do.call(rbind、lapply(list_df、function(x) x[x$names %in% intersect_names, ])), function(x) abs(mean(x)))
– ロナク・シャー
2020 年 9 月 5 日 6:21