R - DPLYR 通过在另一个数据帧上应用汇总函数来计算新列



我想在一个名为df的数据帧中创建一个新列(CNT)。该值将使用包中的summarise函数dplyr计算。它应该返回一个数字,因为我需要在另一个数据帧中计算一列 (= cars ),但是过滤的条件由 2 列 df 中的值决定。

数据帧:

library(dplyr)
df <- data.frame("my_speed" = 11:20, "my_dist" = c(17,20,15,17,21,23,28,36,50,80))

例如,这是df第一行的计算。

x=df[1,1]
y=df[1,2]
cars %>% 
group_by(speed) %>% 
filter(speed==x & dist==y) %>% 
summarise(count=n()) %>% 
select (count)

我正在尝试弄清楚如何使用summarise()或其他方法来轻松执行此操作。请注意,如果summarise()返回任何记录,则应显示零。

df %>% 
rowwise() %>%
filter(speed==my_spped & dist==my_dist) %>% 
summarise(count=n()) %>% 
select (count) %>% 
mutate(CNT=count)

使用 rowwise ,我们可以直接获取逻辑表达式的sum,而无需做额外的操作

df %>% 
   rowwise %>% 
   mutate(CNT = sum((cars$speed == my_speed) & (cars$dist == my_dist)))
# A tibble: 10 x 3
#   my_speed my_dist   CNT
#      <int>   <dbl> <int>
# 1       11      17     1
# 2       12      20     1
# 3       13      15     0
# 4       14      17     0
# 5       15      21     0
# 6       16      23     0
# 7       17      28     0
# 8       18      36     0
# 9       19      50     0
#10       20      80     0

我们可以定义一个函数

library(tidyverse)
get_count <- function(x, y) {
   cars %>% 
    summarise(count = sum(speed == x & dist == y)) %>% 
    pull(count)
}

并使用map2将其应用于每一行

df %>%
  mutate(CNT = map2(my_speed, my_dist, get_count))

#   my_speed my_dist   CNT
#1        11      17     1
#2        12      20     1
#3        13      15     0
#4        14      17     0
#5        15      21     0
#6        16      23     0
#7        17      28     0
#8        18      36     0
#9        19      50     0
#10       20      80     0

使用 apply 相同的基本 R 等效项将是

get_count <- function(x) {
  nrow(subset(cars, speed == x[1] & dist == x[2]))
}
df$CNT <- apply(df, 1, get_count)

解决方案

library(dplyr)
cars %>%
  count(speed, dist) %>%                   # count unique (speed, dist) pairs
  right_join(dat) %>%                      # join to dat, drop all not in dat
  mutate(CNT = coalesce(n, 0L), n = NULL)  # replace NA, create CNT, drop n

数据

dat <- data.frame(
  speed = 11:20,
  dist = c(17, 20, 15, 17, 21, 23, 28, 36, 50, 80)
  )

输出

# A tibble: 10 x 3
   speed  dist   CNT
   <dbl> <dbl> <int>
 1    11    17     1
 2    12    20     1
 3    13    15     0
 4    14    17     0
 5    15    21     0
 6    16    23     0
 7    17    28     0
 8    18    36     0
 9    19    50     0
10    20    80     0

最新更新