Siéntete en la libertad de divulgar nuestro sitio y códigos en tus redes, necesitamos de tu ayuda para hacer crecer nuestra comunidad.
Solución:
No soy un fan/experto en tidyverse, pero intentaría esto usando un formato largo. Luego, simplemente filtre por índice de fila por grupo y luego ejecute las funciones que desee en una sola columna (mucho más fácil de esta manera).
library(tidyr)
library(dplyr)
Data %>%
gather(variable, value, -Subject, -UniqueNumber) %>% # long format
group_by(Subject) %>% # group by Subject in order to get row counts
filter(row_number() <= UniqueNumber) %>% # filter by row index
summarise(Mean = mean(value), Total = sum(value)) %>% # do the calculations
ungroup()
## A tibble: 3 x 3
# Subject Mean Total
#
# 1 1 0.667 2
# 2 2 0.5 1
# 3 3 1 1
Una forma muy similar de lograr esto podría ser filtrar por los números enteros en los nombres de las columnas. El paso del filtro viene antes del group_by
por lo que potencialmente podría aumentar el rendimiento (¿o no?) pero es menos robusto ya que asumo que las columnas de interés se llaman "Value#"
Data %>%
gather(variable, value, -Subject, -UniqueNumber) %>% #long format
filter(as.numeric(gsub("Value", "", variable, fixed = TRUE)) <= UniqueNumber) %>% #filter
group_by(Subject) %>% # group by Subject
summarise(Mean = mean(value), Total = sum(value)) %>% # do the calculations
ungroup()
## A tibble: 3 x 3
# Subject Mean Total
#
# 1 1 0.667 2
# 2 2 0.5 1
# 3 3 1 1
Solo por diversión, agregando una solución data.table
library(data.table)
data.table(Data) %>%
melt(id = c("Subject", "UniqueNumber")) %>%
.[as.numeric(gsub("Value", "", variable, fixed = TRUE)) <= UniqueNumber,
.(Mean = round(mean(value), 3), Total = sum(value)),
by = Subject]
# Subject Mean Total
# 1: 1 0.667 2
# 2: 2 0.500 1
# 3: 3 1.000 1
Aquí hay otro método que usa tidyr::nest
para recoger el Values
columnas en una lista para que podamos iterar a través de la tabla con map2
. En cada fila, seleccionamos los valores correctos de la Values
list-col y toma la suma o la media respectivamente.
library(tidyverse)
tbl <- read_table2(
"Subject Value1 Value2 Value3 UniqueNumber
001 1 0 1 3
002 0 1 1 2
003 1 1 1 1"
)
tbl %>%
filter(UniqueNumber > 0) %>%
nest(starts_with("Value"), .key = "Values") %>%
mutate(
sum = map2_dbl(UniqueNumber, Values, ~ sum(.y[1:.x], na.rm = TRUE)),
mean = map2_dbl(UniqueNumber, Values, ~ mean(as.numeric(.y[1:.x], na.rm = TRUE))),
)
#> # A tibble: 3 x 5
#> Subject UniqueNumber Values sum mean
#>
#> 1 001 3 2 0.667
#> 2 002 2 1 0.5
#> 3 003 1 1 1
Creado el 2019-02-14 por el paquete reprex (v0.2.1)
Compruebe esta solución:
df %>%
gather(key, val, Value1:Value3) %>%
group_by(Subject) %>%
mutate(
Sum = sum(val[c(1:(UniqueNumber[1]))]),
Mean = mean(val[c(1:(UniqueNumber[1]))]),
) %>%
spread(key, val)
Producción:
Subject UniqueNumber Sum Mean Value1 Value2 Value3
1 001 3 2 0.667 1 0 1
2 002 2 1 0.5 0 1 1
3 003 1 1 1 1 1 1