Суммарные значения каждого столбца во фрейме данных с условным циклом For - PullRequest
0 голосов
/ 04 декабря 2018

Итак, я хочу просмотреть набор данных и суммировать значения из каждого столбца на основе состояния моего первого столбца.Данные и мой код до сих пор выглядят так:

x    v1    v2    v3
1    0     1     5
2    4     2     10 
3    5     3     15
4    1     4     20

for(i in colnames(data)){
    if(data$x>2){
        x1 <-sum(data[[i]])
        }
    else{
        x2 <-sum(data[[i]])
        }
      }

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

Я хочу сложить половину значений из каждого столбца и присвоить им значение x1 и сделать то же самое для остатка, назначив его x2.Я продолжаю получать сообщение об ошибке:

the condition has length > 1 and only the first element will be used

Что я делаю не так, и есть ли лучший способ сделать это?В идеале я хочу таблицу, которая выглядит следующим образом:

       v1    v2    v3
x1     6     7     35
x2     4     3     15

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Не уверен, правильно ли я понял ваше намерение, но вот как бы вы воспроизвели свои результаты с базой R:

df <- data.frame(
  x = c(1:4),
  v1 = c(0, 4, 5, 1),
  v2 = 1:4,
  v3 = (1:4)*5
)

x1 <- colSums(df[df$x > 2, 2:4, drop = FALSE])
x2 <- colSums(df[df$x <= 2, 2:4, drop = FALSE])

Где

  • df[df$x > 2, 2:4, drop = FALSE] создастподмножество df, где строки удовлетворяют df$x > 2, а столбцы равны 2:4 (имеется в виду второй, третий и четвертый столбец), drop = FALSE в основном используется для предотвращения упрощения R в некоторых особых случаях
  • colSums вычисляет сумму по столбцам для подмножества data.frame

Если ваш столбец x действительно является условием (например, logical vector), вы можете просто выполнить

x1 <- colSums(df[df$x, 2:4, drop = FALSE])
x2 <- colSums(df[!df$x, 2:4, drop = FALSE])

Обратите внимание, что для получения результатов не требуется цикл, при использовании R вы должны максимально использовать векторизованные функции.

В более общем случае вы можете выполнить такое агрегирование с помощью aggregate:

aggregate(df[, 2:4], by = list(condition = df$x <= 2), FUN = sum)
0 голосов
/ 04 декабря 2018

Вот решение dplyr.Сначала я определяю фрейм данных.

df <- read.table(text = "x    v1    v2    v3
1    0     1     5
2    4     2     10 
3    5     3     15
4    1     4     20", header = TRUE)  

#   x v1 v2 v3
# 1 1  0  1  5
# 2 2  4  2 10
# 3 3  5  3 15
# 4 4  1  4 20

Затем я создаю метку (x_check), чтобы указать, к какой группе принадлежит каждая строка на основе вашего критерия (x > 2), сгруппировать по этой меткеи суммируйте каждый столбец с v в его имени, используя sum.

# Load library
library(dplyr)

df %>% 
  mutate(x_check = ifelse(x>2, "x1", "x2")) %>% 
  group_by(x_check) %>% 
  summarise_at(vars(contains("v")), funs(sum))

# # A tibble: 2 x 4
#   x_check    v1    v2    v3
#   <chr>   <int> <int> <int>
# 1 x1          6     7    35
# 2 x2          4     3    15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...