Подсчитать количество значений, которые меньше текущего значения - PullRequest
0 голосов
/ 23 ноября 2018

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

data <- data.frame(input = c(1,1,1,1,2,2,3,5,5,5,5,6))

    input
1      1
2      1
3      1
4      1
5      2
6      2
7      3
8      5
9      5
10     5
11     5
12     6

Результаты, которые я ожидаю получить, примерно такие.Например, для наблюдений 5 и 6 (со значением 2) есть 4 наблюдения со значением 1, меньшим, чем их значение 2. Следовательно, count имеет значение 4.

    input count
1      1     0
2      1     0
3      1     0
4      1     0
5      2     4
6      2     4
7      3     6
8      5     7
9      5     7
10     5     7
11     5     7
12     6    11

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

data <- data.frame(id = c(1,1,2,2,2,3,3,4,4,4,4,4), 
input = c(1,1,1,1,2,2,3,5,5,5,5,6), 
count=c(0,0,0,0,2,0,1,0,0,0,0,4))

   id input count
1   1     1     0
2   1     1     0
3   2     1     0
4   2     1     0
5   2     2     2
6   3     2     0
7   3     3     1
8   4     5     0
9   4     5     0
10  4     5     0
11  4     5     0
12  4     6     4

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

Вот вариант с tidyverse

library(tidyverse)
data %>%
   mutate(count = map_int(input, ~ sum(.x > input))) 
#    input count
#1      1     0
#2      1     0
#3      1     0
#4      1     0
#5      2     4
#6      2     4
#7      3     6
#8      5     7
#9      5     7
#10     5     7
#11     5     7
#12     6    11

Обновить

С обновленными данными добавить группу по 'id' в приведенном выше коде

data %>% 
  group_by(id) %>% 
  mutate(count1 = map_int(input, ~ sum(.x > input)))
# A tibble: 12 x 4
# Groups:   id [4]
#      id input count count1
#   <dbl> <dbl> <dbl>  <int>
# 1     1     1     0      0
# 2     1     1     0      0
# 3     2     1     0      0
# 4     2     1     0      0
# 5     2     2     2      2
# 6     3     2     0      0
# 7     3     3     1      1
# 8     4     5     0      0
# 9     4     5     0      0
#10     4     5     0      0
#11     4     5     0      0
#12     4     6     4      4
0 голосов
/ 23 ноября 2018

1 .outer и rowSums

data$count <- with(data, rowSums(outer(input, input, `>`)))

2 .table и cumsum

tt <- cumsum(table(data$input))
v <- setNames(c(0, head(tt, -1)), c(head(names(tt), -1), tail(names(tt), 1)))
data$count <- v[match(data$input, names(v))]

3 .data.table неэквивалентное объединение

Возможно, более эффективно с неэквивалентным объединением в data.table.Подсчитайте количество строк (.N) для каждого совпадения (by = .EACHI).

library(data.table)
setDT(data)
data[data, on = .(input < input), .N, by = .EACHI]

Если ваши данные сгруппированы по 'id', как в вашем обновлении, присоединитесь к этой переменной какскважина:

data[data, on = .(id, input < input), .N, by = .EACHI]

#     id input N
#  1:  1     1 0
#  2:  1     1 0
#  3:  2     1 0
#  4:  2     1 0
#  5:  2     2 2
#  6:  3     2 0
#  7:  3     3 1
#  8:  4     5 0
#  9:  4     5 0
# 10:  4     5 0
# 11:  4     5 0
# 12:  4     6 4
0 голосов
/ 23 ноября 2018

В базе R мы можем использовать sapply и для каждого input посчитать, сколько значений больше, чем он сам.

data$count <- sapply(data$input, function(x) sum(x > data$input))

data

#   input count
#1      1     0
#2      1     0
#3      1     0
#4      1     0
#5      2     4
#6      2     4
#7      3     6
#8      5     7
#9      5     7
#10     5     7
#11     5     7
#12     6    11

С dplyr один способ будет использовать rowwise функционируют и следуют той же логике.

library(dplyr)

data %>%
  rowwise() %>%
  mutate(count = sum(input > data$input))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...