Получение rowSums для трехкратных записей и сохранение только одного с наибольшим значением - PullRequest
2 голосов
/ 28 июня 2019

У меня есть фрейм данных с 163 наблюдениями и 65 столбцами с некоторыми данными о животных.163 наблюдения были получены от 56 животных, и у каждого предполагалось, что они имели трехкратные записи, но некоторая информация была потеряна, поэтому для большинства животных у меня есть трижды («A», «B», «C»), а для некоторых я имеютолько дубликаты (которые варьируются между «A» и «B», «A» и «C» и «B» и «C»).

Столбцы 13:65 содержат некоторую информацию, которую я хотел бы суммировать, и сохраняют только одну тройку с более высоким значением rowSums.Таким образом, мой фрейм данных будет выглядеть примерно так:

  ID    Trip     Acet    Cell   Fibe   Mega   Tera
1   4      A        2       4      9      8      3  
2   4      B        9       3      7      5      5  
3   4      C        1       2      4      8      6 
4   12     A        4       6      7      2      3 
5   12     B        6       8      1      1      2 
6   12     C        5       5      7      3      3 

Я не уверен, что мне нужно написать собственную функцию или цикл, или какова лучшая альтернатива на самом деле - извините, я до сих поручиться и, к сожалению, для меня, я не думаю, что я программист, так что это делает вещи еще более сложными ...

Так что я хочу знать, чтобы держать строки 2 и 6 (которые имеют самые высокие суммы строк)среди трех экземпляров на животное), но для всего фрейма данных.В результате я хочу получить

    ID    Trip    Acet    Cell   Fibe   Mega   Tera
1   4      B       9       3      7      5      5  
2   12     C       5       5      7      3      3

ДЕЙСТВИТЕЛЬНО извините, если вопрос плохо разработан или не имеет смысла, я впервые задаю вопрос здесь, и я только недавно начал изучать R.

Ответы [ 2 ]

1 голос
/ 28 июня 2019

Вот один из способов.

library(tidyverse)

dat2 <- dat %>%
  mutate(Sum = rowSums(select(dat, starts_with("V")))) %>%
  group_by(ID) %>%
  filter(Sum == max(Sum)) %>%
  select(-Sum) %>%
  ungroup()
dat2
# # A tibble: 2 x 7
#      ID Trip     V1    V2    V3    V4    V5
#   <int> <fct> <int> <int> <int> <int> <int>
# 1     4 B         9     3     7     5     5
# 2    12 C         5     5     7     3     3

Вот еще один. Этот метод обеспечивает сохранение только одной строки, даже если имеется несколько строк с суммой строк, равной максимуму.

dat3 <- dat %>%
  mutate(Sum = rowSums(select(dat, starts_with("V")))) %>%
  arrange(ID, desc(Sum)) %>%
  group_by(ID) %>%
  slice(1) %>%
  select(-Sum) %>%
  ungroup()
dat3
# # A tibble: 2 x 7
#      ID Trip     V1    V2    V3    V4    V5
#   <int> <fct> <int> <int> <int> <int> <int>
# 1     4 B         9     3     7     5     5
# 2    12 C         5     5     7     3     3

DATA

dat <- read.table(text = "  ID    Trip     V1     V2    V3    V4    V5
1   4      A       2      4     9     8     3  
2   4      B       9      3     7     5     5  
3   4      C       1      2     4     8     6 
4   12     A       4      6     7     2     3 
5   12     B       6      8     1     1     2 
6   12     C       5      5     7     3     3 ",
                  header = TRUE)
1 голос
/ 28 июня 2019

Мы можем создать суммы строк отдельно и использовать их для поиска строки с максимальными суммами строк, используя ave. Затем используйте логический вектор для подстановки строк набора данных

nm1 <- startsWith(names(df1), "V")

OP обновил имена столбцов. В этом случае либо индекс

nm1 <- 3:7

Или выберите столбцы с помощью setdiff

nm1 <- setdiff(names(df1), c("ID", "Trip"))

v1 <- rowSums(df1[nm1], na.rm = TRUE)
i1 <- with(df1, v1 == ave(v1, ID, FUN = max))
df1[i1,]
#  ID Trip V1 V2 V3 V4 V5
#2  4    B  9  3  7  5  5
#6 12    C  5  5  7  3  3

данные

df1 <- structure(list(ID = c(4L, 4L, 4L, 12L, 12L, 12L), Trip = structure(c(1L, 
2L, 3L, 1L, 2L, 3L), .Label = c("A", "B", "C"), class = "factor"), 
    V1 = c(2L, 9L, 1L, 4L, 6L, 5L), V2 = c(4L, 3L, 2L, 6L, 8L, 
    5L), V3 = c(9L, 7L, 4L, 7L, 1L, 7L), V4 = c(8L, 5L, 8L, 2L, 
    1L, 3L), V5 = c(3L, 5L, 6L, 3L, 2L, 3L)), 
    class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))
...