r 中具有可变条件的跨列计数
Tally across columns with variable condition in r
我正在尝试对超过相应限制变量的值的数据框的列进行统计。这是一个 similar problem 但对于每个点,条件可能会改变,因此 rowSums
不是一个选项。我对我在下面尝试的解决方案的修改、任何更有效的方法以及任何有助于解决此问题的更简单的方法感兴趣。
library(tidyverse)
set.seed(234)
ex_dat <- tibble(a = rnorm(n = 6, mean = 1),
a_lim = 0.75,
b = rnorm(n = 6, mean = 0.5),
b_lim = 0.333,
c = rnorm(n = 6, mean = 1.5),
c_lim = 1.0,
d = rnorm(n = 6, mean = 1.5),
d_lim = 1.25)
ex_dat %>%
rowwise() %>%
mutate(tally = sum(map_lgl(.x = c("a","b","c","d"),
.f = ~(noquote(.x) > noquote(paste0(.x,"_lim")))), na.rm = T))
例如,假设满足所有 4 个条件,期望的结果是此处的 'tally' 列在第一行中读取 4。然后,假设只超过了 2 个限制,第二行应该读取 2。
我在这里尝试了这种方法的一些变体,使用 bang-bang 运算符强制计算 map
函数的 .f
参数中的变量。到目前为止,就我的头脑而言,这种尝试和无声的失败似乎是最接近和最明智的。显然,我对非标准评估没有很牢固的把握,所以我对 !!
和 sym()
的尝试并没有让我走得太远。
再次重申,如果有人看到我在迂回或低效地解决这个问题,我欢迎重定向。谢谢。
这里有一种稍微不同的方法来解决您的问题。它依赖于不等式如果为真则为 1,如果为假则为 0 的“技巧”。因此,您可以根据它们的极限评估 a、b、c 和 d,然后对 4 个不等式的评估求和。
library(dplyr)
ex_dat_tally<-ex_dat %>%
mutate(tally=(a>a_lim)+(b>b_lim)+(c>c_lim)+(d>d_lim))
我发现这种基本的 R 方法直观、简单,而且应该很快,因为我们使用矢量化方法直接处理数据帧。
lim_cols <- grep('lim', names(ex_dat), value = TRUE)
cols <- sub('_lim', '', lim_cols)
ex_dat$tally <- rowSums(ex_dat[cols] > ex_dat[lim_cols])
ex_dat
# a a_lim b b_lim c c_lim d d_lim tally
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1.66 0.75 0.709 0.333 1.47 1 2.03 1.25 4
#2 -1.05 0.75 -2.54 0.333 2.01 1 1.52 1.25 2
#3 -0.499 0.75 0.0131 0.333 2.49 1 1.71 1.25 2
#4 2.47 0.75 -0.588 0.333 1.80 1 2.52 1.25 3
#5 2.46 0.75 0.558 0.333 0.570 1 1.91 1.25 3
#6 1.14 0.75 1.60 0.333 1.58 1 0.795 1.25 3
这里我们创建了两组列 lim_cols
和 cols
。
lim_cols
#[1] "a_lim" "b_lim" "c_lim" "d_lim"
cols
#[1] "a" "b" "c" "d"
两两比较,用rowSums
算出满足条件的有多少
我正在尝试对超过相应限制变量的值的数据框的列进行统计。这是一个 similar problem 但对于每个点,条件可能会改变,因此 rowSums
不是一个选项。我对我在下面尝试的解决方案的修改、任何更有效的方法以及任何有助于解决此问题的更简单的方法感兴趣。
library(tidyverse)
set.seed(234)
ex_dat <- tibble(a = rnorm(n = 6, mean = 1),
a_lim = 0.75,
b = rnorm(n = 6, mean = 0.5),
b_lim = 0.333,
c = rnorm(n = 6, mean = 1.5),
c_lim = 1.0,
d = rnorm(n = 6, mean = 1.5),
d_lim = 1.25)
ex_dat %>%
rowwise() %>%
mutate(tally = sum(map_lgl(.x = c("a","b","c","d"),
.f = ~(noquote(.x) > noquote(paste0(.x,"_lim")))), na.rm = T))
例如,假设满足所有 4 个条件,期望的结果是此处的 'tally' 列在第一行中读取 4。然后,假设只超过了 2 个限制,第二行应该读取 2。
我在这里尝试了这种方法的一些变体,使用 bang-bang 运算符强制计算 map
函数的 .f
参数中的变量。到目前为止,就我的头脑而言,这种尝试和无声的失败似乎是最接近和最明智的。显然,我对非标准评估没有很牢固的把握,所以我对 !!
和 sym()
的尝试并没有让我走得太远。
再次重申,如果有人看到我在迂回或低效地解决这个问题,我欢迎重定向。谢谢。
这里有一种稍微不同的方法来解决您的问题。它依赖于不等式如果为真则为 1,如果为假则为 0 的“技巧”。因此,您可以根据它们的极限评估 a、b、c 和 d,然后对 4 个不等式的评估求和。
library(dplyr)
ex_dat_tally<-ex_dat %>%
mutate(tally=(a>a_lim)+(b>b_lim)+(c>c_lim)+(d>d_lim))
我发现这种基本的 R 方法直观、简单,而且应该很快,因为我们使用矢量化方法直接处理数据帧。
lim_cols <- grep('lim', names(ex_dat), value = TRUE)
cols <- sub('_lim', '', lim_cols)
ex_dat$tally <- rowSums(ex_dat[cols] > ex_dat[lim_cols])
ex_dat
# a a_lim b b_lim c c_lim d d_lim tally
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1.66 0.75 0.709 0.333 1.47 1 2.03 1.25 4
#2 -1.05 0.75 -2.54 0.333 2.01 1 1.52 1.25 2
#3 -0.499 0.75 0.0131 0.333 2.49 1 1.71 1.25 2
#4 2.47 0.75 -0.588 0.333 1.80 1 2.52 1.25 3
#5 2.46 0.75 0.558 0.333 0.570 1 1.91 1.25 3
#6 1.14 0.75 1.60 0.333 1.58 1 0.795 1.25 3
这里我们创建了两组列 lim_cols
和 cols
。
lim_cols
#[1] "a_lim" "b_lim" "c_lim" "d_lim"
cols
#[1] "a" "b" "c" "d"
两两比较,用rowSums
算出满足条件的有多少