我正在尝试构建嵌套的自定义函数来获取交叉表的输出。许多交叉表函数只允许在表内进行计算,而我需要将表中的每个值除以来自不同逻辑的值。但是因为我需要很多交叉表,所以我想构建一个函数,它将交叉表和每个值除以外部数据结合起来。
以下是初始数据:
Key <- c("Yellow", "Yellow", "Red", "Blue", "Yellow", "Red", "Blue", "Yellow", "Yellow", "Red", "Blue", "Yellow", "Red", "Blue", "Blue")
Speed <- c("Slow", "Fast", "Mid", "Fast", "Mid", "Slow", "Slow", "Mid", "Slow", "Fast", "Mid", "Fast", "Mid", "Fast", "Mid")
ID <- factor(c(1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 8, 9, 9, 10))
init_dt <- data.frame(ID, Key, Speed)
和第一个函数的交叉表与简单的频率:
crosstab <- function(dt, col_y, col_x){
col_y = sym(col_y)
col_x = sym(col_x)
dt %>% group_by(!!col_y, !!col_x) %>%
tally() %>%
spread(!!col_x, n)
}
当我将这个函数应用于初始数据时,我得到以下结果:
crosstab_key <- crosstab(init_dt, "Key", 'Speed')
crosstab_key
# A tibble: 3 × 4
# Groups: Key [3]
Key Fast Mid Slow
<chr> <int> <int> <int>
1 Blue 2 2 1
2 Red 1 2 1
3 Yellow 2 2 2
之后,我使用相同的初始数据但单独的函数计算除法的值:
div <- function(dt, id, col_y, col_x) {
col_y = sym(col_y)
id = sym(id)
col_x = sym(col_x)
dt%>% select(id, col_y, col_x) %>%
group_by(!!col_x) %>%
distinct(!!id) %>%
summarise(count = n())
}
当应用此函数时,我得到以下结果:
div_speed <- div(init_dt, "ID", "Key", "Speed")
div_speed
# A tibble: 3 × 2
Speed count
<chr> <int>
1 Fast 5
2 Mid 6
3 Slow 4
我想将交叉表crosstab_key
中的每个值除以div_speed
中的值。我可以这样合并函数:
crosstab(init_dt, "Key", 'Speed') %>% rowwise() %>%
mutate(across(everything())/div(init_dt, "ID", "Key", "Speed")$count)
# A tibble: 3 × 4
# Rowwise: Key
Key Fast Mid Slow
<chr> <dbl> <dbl> <dbl>
1 Blue 0.4 0.333 0.25
2 Red 0.2 0.333 0.25
3 Yellow 0.4 0.333 0.5
但是我想避免单独使用div
函数,所以我的问题是如何将这两个函数组合在一起(正如您所看到的,参数是相同的:dt, id, col_y, col_x
,因为它们来自相同的初始 Dataframe ),这样我就不需要在每次需要将交叉表除以某些值时创建div_
对象。最重要的是,我还需要将每个值四舍五入到四位小数mutate_at(2:4, funs(round(., 4)))
。
2条答案
按热度按时间vh0rcniy1#
关于Tidyverse
您可以将两个功能简化为一个。
创建于2023-03-23带有reprex v2.0.2
按照您的步骤,我首先计算了每个
col_x
对应的id
s的不同个数。然后,你要计算每
col_x
和col_y
的id
的数量,并将其除以我们之前计算的数量。我们可以分两步来做:
但是
pivot_wider
中的values_fn
参数允许我们对扩展列进行操作。因此我们可以一次完成。带table
看起来你可以用
table
和prop.table
得到相同的结果:创建于2023-03-23带有reprex v2.0.2
将4位数强制写入
kable
ncecgwcz2#
这里有一种方法可以将它们组合起来,使交叉制表符的功能。我注意到你正在使用
spread()
,但pivot_wider()
是替代功能,如果你有访问权限,应该使用它。