#r #sapply
#r #sapply
Вопрос:
Пример данных
data=data.frame("group"=c(rep(0:1,10)),
"value1" = c(1:10),
"value2" = seq(11:20),
"value3" = as.factor(rep(1:3,length=10)))
У меня есть фрейм данных «data» с целью создания нового фрейма данных, как показано на рисунке. ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ, ЧТО ЗНАЧЕНИЕ 3 ЯВЛЯЕТСЯ ФАКТОРНОЙ ПЕРЕМЕННОЙ. Итак, я хотел бы сообщить n и процент. Для каждой группы, как на картинке.
Я знаю, что нужно оценивать минимальные и максимальные значения отдельно следующим образом
value1_min0 = min(data$value1)[data$group==1]
value1_max0 = max(data$value1)[data$group==1]
value1_min1 = min(data$value1)[data$group==0]
value1_max1 = max(data$value1)[data$group==0]
Но есть ли лучший способ сделать это более эффективно?
Комментарии:
1. Вы хотите для всех значений или только для значения 1?
2. Все значения в образцах данных для обеих групп, как на рисунке. @NelsonGon спасибо
Ответ №1:
База R
Используйте aggregate для числовых переменных и table / prop.table для коэффициента.
ag <- aggregate(cbind(value1, value2) ~ group, data,
function(x) c(min = min(x), max = max(x)))
tab12 <- as.data.frame.matrix(setNames(as.data.frame(t(ag[-1])),
ag[[1]]))
counts <- table(data$group)
tab3 <- prop.table(table(group = data$value3, value3 = data$group), 2)
rownames(tab3) <- paste("value3", rownames(tab3), sep = " = ")
rbind(tab12, n = counts, as.data.frame.matrix(tab3))
дает следующее
0 1
value1.min 1.0 2.0
value1.max 9.0 10.0
value2.min 1.0 2.0
value2.max 9.0 10.0
n 10.0 10.0
value3 = 1 0.4 0.4
value3 = 2 0.2 0.4
value3 = 3 0.4 0.2
sqldf
Эта альтернатива немного утомительна, но она проста:
library(sqldf)
res <- sqldf('select
[group],
min(value1) [value1.min],
max(value1) [value1.max],
min(value2) [value2.min],
max(value2) [value2.max],
count(*) n,
avg(value3 = 1) [value3 == 1],
avg(value3 = 2) [value3 == 2],
avg(value3 = 3) [value3 == 3]
from data
group by [group]')
setNames(as.data.frame(t(res[-1])), res$group)
предоставление:
0 1
value1.min 1.0 2.0
value1.max 9.0 10.0
value2.min 1.0 2.0
value2.max 9.0 10.0
n 10.0 10.0
value3 == 1 0.4 0.4
value3 == 2 0.2 0.4
value3 == 3 0.4 0.2
skimr
Используя пакет skimr, мы можем сделать это:
library(dplyr)
library(skimr)
library(tidyr)
# L <- list("fraction = 1" = function(x) mean(x == 1),
# "fraction = 2" = function(x) mean(x == 2),
# "fraction = 3" = function(x) mean(x == 3))
levs <- levels(data$value3)
L <- lapply(levs, function(lv) function(x) mean(x == lv))
names(L) <- paste("fraction =", levs)
skim_with(integer = list(min = min, max = max),
factor = c(L, n = length), append = FALSE)
data %>%
group_by(group) %>%
skim %>%
ungroup %>%
select(group, variable, stat, value) %>%
spread(group, value)
дает следующее:
# A tibble: 8 x 4
variable stat `0` `1`
<chr> <chr> <dbl> <dbl>
1 value1 max 9 10
2 value1 min 1 2
3 value2 max 9 10
4 value2 min 1 2
5 value3 fracion = 1 0.4 0.4
6 value3 fracion = 2 0.2 0.4
7 value3 fracion = 3 0.4 0.2
8 value3 n 10 10
Обновить
Пересмотренное базовое решение; добавлены решения sqldf и skimr. Улучшенное решение skimr.
Комментарии:
1. большое спасибо, но на самом деле value3 является факторной переменной, поэтому возможно ли вместо min max сделать n и% для каждой из категорий, в том числе, если отсутствуют значения?
2. полностью переработано
Ответ №2:
Используя dplyr
(>=0.8.0 синтаксис):
library(dplyr)
df %>%
group_by(group) %>%
summarise_all(list(~min(.),~max(.)))
Результат:
# A tibble: 2 x 7
group value1_min value2_min value3_min value1_max value2_max value3_max
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 0 1 1 1 9 9 3
2 1 2 2 1 10 10 3
Ответ №3:
Используя dplyr
и tidyr
:
library(dplyr)
library(tidyr)
data %>%
group_by(group) %>%
summarize(value1_min = min(value1),
value1_max = max(value1),
value2_min = min(value2),
value2_max = max(value2),
value3_n = length(unique(value3)),
value3_perc1 = length(sum(value3==1))/length(unique(value3)),
value3_perc2 = length(sum(value3==2))/length(unique(value3)),
value3_perc3 = length(sum(value3==3))/length(unique(value3))
) %>%
gather(review, value, -group) %>%
spread(group, value)
Результат:
# A tibble: 7 x 3
review `0` `1`
<chr> <dbl> <dbl>
1 value1_max 9.00 10.0
2 value1_min 1.00 2.00
3 value2_max 9.00 10.0
4 value2_min 1.00 2.00
5 value3_n 3.00 3.00
6 value3_perc1 0.333 0.333
7 value3_perc2 0.333 0.333
8 value3_perc3 0.333 0.333
Комментарии:
1. Ошибка:
var
необходимо вычислить единственное число или имя столбца, а не целочисленный вектор