决定数据框中有效数字的数量
deciding on the number of significant digits in a data frame
我有一个巨大的数据框,下面给出了一个 3 列 11 行的示例:
df <- structure(list(A = c(61960, 273, 439, 38877, 75325, 80929,
23028, 57240, 10140, 25775, 7286), B = c(10, 12, 11, 13, 2, 1, 1,
1, 1, 1, 1), C = c(122, 140, 163, 12, 190, 16, 14, 18, 15, 17, 16
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-11L))
对于数据框的每一列,我想计算该列中每个数量级的有效数字的中位数。
例如,对于上面的 A 列,存在 3 个数量级(10^3、10^4、10^5)。第一个数字有 4 位(最后一个零不算),第二个有 3 位,依此类推。
我的输出应该是每一列的列表,其中一个元素是一个包含数量级的向量,第二个元素是有效数字的中位数。
所以对于每一列我都期待一个列表,我的输出将是一个列表列表。例如对于 A 列:
L[["A"]] = list(c(5,4,3), c(5, 4, 3))
为什么是这个列表?在 A 列中有 3 个不同的数量级:10^5、10^4、10^3。 10^5 o.o.m 有效数字的中位数是 5,10^4, 4 和 10^3, 3.
有没有办法有效地做到这一点?使用 mutate
或 map
(不是 apply
,因为这与使用循环相同)。
我们可以通过遍历列来完成此操作,然后按列的 nchar
分组,用 sub
删除末尾的 0,得到 median
和 return 中位数的 list
以及 tapply
中的分组变量(return 编辑为命名向量的名称)
lapply(df, function(x) {
x1 <- tapply(nchar(sub("0+$", "", x)), nchar(x), FUN = median )
list(as.integer(names(x1)), as.numeric(x1))
})
#$A
#$A[[1]]
#[1] 3 4 5
#$A[[2]]
#[1] 3 4 5
#$B
#$B[[1]]
#[1] 1 2
#$B[[2]]
#[1] 1 2
#$C
#$C[[1]]
#[1] 2 3
#$C[[2]]
#[1] 2.0 2.5
或者这也可以通过 tidyverse
和 return 作为单个数据集来完成
library(tidyverse)
df %>%
mutate_all(str_remove, "0+$") %>%
map2_dfr(., df, ~
tibble(x = nchar(.x), grp = nchar(.y)) %>%
group_by(grp) %>%
summarise(x = median(x)), .id = 'colName')
# A tibble: 7 x 3
# colName grp x
# <chr> <int> <dbl>
#1 A 3 3
#2 A 4 4
#3 A 5 5
#4 B 1 1
#5 B 2 2
#6 C 2 2
#7 C 3 2.5
我有一个巨大的数据框,下面给出了一个 3 列 11 行的示例:
df <- structure(list(A = c(61960, 273, 439, 38877, 75325, 80929,
23028, 57240, 10140, 25775, 7286), B = c(10, 12, 11, 13, 2, 1, 1,
1, 1, 1, 1), C = c(122, 140, 163, 12, 190, 16, 14, 18, 15, 17, 16
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-11L))
对于数据框的每一列,我想计算该列中每个数量级的有效数字的中位数。
例如,对于上面的 A 列,存在 3 个数量级(10^3、10^4、10^5)。第一个数字有 4 位(最后一个零不算),第二个有 3 位,依此类推。
我的输出应该是每一列的列表,其中一个元素是一个包含数量级的向量,第二个元素是有效数字的中位数。 所以对于每一列我都期待一个列表,我的输出将是一个列表列表。例如对于 A 列:
L[["A"]] = list(c(5,4,3), c(5, 4, 3))
为什么是这个列表?在 A 列中有 3 个不同的数量级:10^5、10^4、10^3。 10^5 o.o.m 有效数字的中位数是 5,10^4, 4 和 10^3, 3.
有没有办法有效地做到这一点?使用 mutate
或 map
(不是 apply
,因为这与使用循环相同)。
我们可以通过遍历列来完成此操作,然后按列的 nchar
分组,用 sub
删除末尾的 0,得到 median
和 return 中位数的 list
以及 tapply
中的分组变量(return 编辑为命名向量的名称)
lapply(df, function(x) {
x1 <- tapply(nchar(sub("0+$", "", x)), nchar(x), FUN = median )
list(as.integer(names(x1)), as.numeric(x1))
})
#$A
#$A[[1]]
#[1] 3 4 5
#$A[[2]]
#[1] 3 4 5
#$B
#$B[[1]]
#[1] 1 2
#$B[[2]]
#[1] 1 2
#$C
#$C[[1]]
#[1] 2 3
#$C[[2]]
#[1] 2.0 2.5
或者这也可以通过 tidyverse
和 return 作为单个数据集来完成
library(tidyverse)
df %>%
mutate_all(str_remove, "0+$") %>%
map2_dfr(., df, ~
tibble(x = nchar(.x), grp = nchar(.y)) %>%
group_by(grp) %>%
summarise(x = median(x)), .id = 'colName')
# A tibble: 7 x 3
# colName grp x
# <chr> <int> <dbl>
#1 A 3 3
#2 A 4 4
#3 A 5 5
#4 B 1 1
#5 B 2 2
#6 C 2 2
#7 C 3 2.5