如何按条件计算另一列的列数

How to count number of columns by condition on another column

我有一个如下所示的数据框:

data <- as.data.frame(cbind('01-01-2018' = c(1.2,3.1,0.7,-0.3,2.0), '02-01-2018' = c(-0.1, 2.4, 4.9,-3.3,-2.7), '03-01-2018' = c(3.4, -2.6, -1.8, 0.1, 0.3)))

  01-01-2018  02-01-2018  03-01-2018
1      1.2       -0.1        3.4
2      3.1        2.4       -2.6
3      0.7        4.9       -1.8
4     -0.3       -3.3        0.1
5      2.0       -2.7        0.3

我想计算每行有多少次,一个值大于相应行的平均值。

data$mn <- apply(data, 1, mean) 

  01-01-2018 02-01-2018 03-01-2018         mn
1        1.2       -0.1        3.4  1.5000000
2        3.1        2.4       -2.6  0.9666667
3        0.7        4.9       -1.8  1.2666667
4       -0.3       -3.3        0.1 -1.1666667
5        2.0       -2.7        0.3 -0.1333333

我最后一次尝试如下:

df$events <- apply(data, 1, function(x) sum(x > data$mn))

uhi_events <- numeric(nrow(data))

for (i in 1:nrow(data)) {
  
  uhi <- data[[6]][[i]][["values"]]
  uhi_events[i] <- sum(uhi)
  
}

data$uhi_events <- uhi_events

有没有更高效的选择?

编辑:

如果条件在另一列上,比如说data$c1,不是通过简单的公式得到的怎么办?

data$md <- apply(data, 1, median) 

  01-01-2018 02-01-2018 03-01-2018         md
1        1.2       -0.1        3.4  1.5000000
2        3.1        2.4       -2.6  0.9666667
3        0.7        4.9       -1.8  1.2666667
4       -0.3       -3.3        0.1 -1.1666667
5        2.0       -2.7        0.3 -0.1333333

使用用户定义的函数从逻辑运算求和(逻辑向量被 sum() 强制转换为整数向量,使得 TRUE = 1 且 FALSE = 0)

data$uhi_events <- 
  apply(data, 1, function(i){
    sum(i>mean(i))
  })
library(data.table)
setDT(data)
data[, above_mean := rowSums(.SD > rowMeans(.SD))]
#    01-01-2018 02-01-2018 03-01-2018 above_mean
# 1:        1.2       -0.1        3.4          1
# 2:        3.1        2.4       -2.6          2
# 3:        0.7        4.9       -1.8          1
# 4:       -0.3       -3.3        0.1          2
# 5:        2.0       -2.7        0.3          2

在评论中编辑问题
与第一列中的值进行比较

data[, above_col1 := rowSums(.SD > `01-01-2018`)]
#    01-01-2018 02-01-2018 03-01-2018      above_col1
# 1:        1.2       -0.1        3.4               1
# 2:        3.1        2.4       -2.6               0
# 3:        0.7        4.9       -1.8               1
# 4:       -0.3       -3.3        0.1               1
# 5:        2.0       -2.7        0.3               0

使用 rowMeansrowSums:

data$cnt <- rowSums(data > rowMeans(data))

data
#   01-01-2018 02-01-2018 03-01-2018 cnt
# 1        1.2       -0.1        3.4   1
# 2        3.1        2.4       -2.6   2
# 3        0.7        4.9       -1.8   1
# 4       -0.3       -3.3        0.1   2
# 5        2.0       -2.7        0.3   2

如果该列已被计算,请将 rowMeans 替换为现有列 data$c1:

#get index excluding "c1":
ix <- grep("c1", colnames(data), invert = TRUE)
data$cnt <- rowSums(data[, ix ] > data$c1)

使用dplyr方法:

library(dplyr)

data <- as.data.frame(cbind('01-01-2018' = c(1.2,3.1,0.7,-0.3,2.0), '02-01-2018' = c(-0.1, 2.4, 4.9,-3.3,-2.7), '03-01-2018' = c(3.4, -2.6, -1.8, 0.1, 0.3)))

data$mm <- apply(data,1,median)

data %>% 
  rowwise %>% 
  mutate(count = sum(c_across(1:3) > mm))

#> # A tibble: 5 × 5
#> # Rowwise: 
#>   `01-01-2018` `02-01-2018` `03-01-2018`    mm count
#>          <dbl>        <dbl>        <dbl> <dbl> <int>
#> 1          1.2         -0.1          3.4   1.2     1
#> 2          3.1          2.4         -2.6   2.4     1
#> 3          0.7          4.9         -1.8   0.7     1
#> 4         -0.3         -3.3          0.1  -0.3     1
#> 5          2           -2.7          0.3   0.3     1