R语言 如何从数组的子集中逐行计数不同值的个数?

4smxwvx5  于 2023-09-27  发布在  其他
关注(0)|答案(4)|浏览(89)

我有一个这样的 Dataframe :

  1. df = read.table(text="ID L1 L2 L3 L4 L5 L6 L7 L8 S1 S2 S3 S4 S5 S6 S7 S8
  2. T1 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2
  3. T2 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  4. T3 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  5. T4 0 0 0 1 0 0 0 0 0 1 2 2 1 1 1 1
  6. T5 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  7. T6 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  8. T7 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  9. T8 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0
  10. T9 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2", header=T, stringsAsFactors=F)

我想在两个有列的子集中分别按行计数“0”、“1”和“2”:grep(“^L”,names(df))或grep(“^S”,names(df))。然后用两个子集中的最大值数创建两个新列。结果是这样的:

  1. ID L S
  2. T1 0 2
  3. T2 0 2
  4. T3 0 2
  5. T4 0 1
  6. T5 0 2
  7. T6 0 2
  8. T7 0 2
  9. T8 0 0
  10. T9 0 2

感谢任何帮助!

s71maibg

s71maibg1#

对我来说,最简单的方法是将数据旋转得更长,将所有SL值分别放在一列中。然后,您可以按ID进行分组,并在组内找到LS的模态值。我做了一个叫做“modal”的小函数来查找模态值。

  1. df = read.table(text="ID L1 L2 L3 L4 L5 L6 L7 L8 S1 S2 S3 S4 S5 S6 S7 S8
  2. T1 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2
  3. T2 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  4. T3 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  5. T4 0 0 0 1 0 0 0 0 0 1 2 2 1 1 1 1
  6. T5 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  7. T6 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  8. T7 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2
  9. T8 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0
  10. T9 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2", header=T, stringsAsFactors=F)
  11. library(tidyr)
  12. library(dplyr)
  13. modal <- function(x){tab <- table(x); names(tab)[which.max(tab)]}
  14. df %>%
  15. pivot_longer(-ID, names_pattern="([A-Z])\\d", names_to=c(".value")) %>%
  16. group_by(ID) %>%
  17. summarise(across(everything(), modal))
  18. #> # A tibble: 9 × 3
  19. #> ID L S
  20. #> <chr> <chr> <chr>
  21. #> 1 T1 0 2
  22. #> 2 T2 0 2
  23. #> 3 T3 0 2
  24. #> 4 T4 0 1
  25. #> 5 T5 0 2
  26. #> 6 T6 0 2
  27. #> 7 T7 0 2
  28. #> 8 T8 0 0
  29. #> 9 T9 0 2

创建于2023-09-11使用reprex v2.0.2

展开查看全部
2cmtqfgy

2cmtqfgy2#

带有aggregate + reshape的基本R选项

  1. aggregate(
  2. cbind(L, S) ~ ID,
  3. reshape(
  4. setNames(df, sub("(\\d)", ".\\1", names(df))),
  5. direction = "long",
  6. idvar = "ID",
  7. varying = -1
  8. ),
  9. \(x) as.integer(names(which.max(table(x))))
  10. )

这给

  1. ID L S
  2. 1 T1 0 2
  3. 2 T2 0 2
  4. 3 T3 0 2
  5. 4 T4 0 1
  6. 5 T5 0 2
  7. 6 T6 0 2
  8. 7 T7 0 2
  9. 8 T8 0 0
  10. 9 T9 0 2
展开查看全部
xtupzzrd

xtupzzrd3#

您可以一次对整个部分执行table,而不是逐行执行。这样应该更快

  1. row_mode_val <- function(df) {
  2. tb <- table(c(row(df)), unlist(df))
  3. as.numeric(colnames(tb)[max.col(tb)])
  4. }
  5. df %>%
  6. transmute(
  7. ID,
  8. L = row_mode_val(across(starts_with('L'))),
  9. S = row_mode_val(across(starts_with('S'))))
  10. #> ID L S
  11. #> 1 T1 0 2
  12. #> 2 T2 0 2
  13. #> 3 T3 0 2
  14. #> 4 T4 0 1
  15. #> 5 T5 0 2
  16. #> 6 T6 0 2
  17. #> 7 T7 0 2
  18. #> 8 T8 0 0
  19. #> 9 T9 0 2

使用具有10k行的数据框进行基准测试。

  1. f1 <- function() {
  2. df %>%
  3. transmute(
  4. ID,
  5. L = row_mode_val(across(starts_with('L'))),
  6. S = row_mode_val(across(starts_with('S')))) %>%
  7. remove_rownames()
  8. }
  9. f2 <- function() {
  10. df |>
  11. summarize(L = mode(c_across(starts_with("L"))),
  12. S = mode(c_across(starts_with("S"))), .by = ID) %>%
  13. remove_rownames()
  14. }
  15. # make bigger example
  16. df <- df[sample(nrow(df), 1e4, T),] %>%
  17. mutate(ID = paste0('T', row_number()))
  18. bench::mark(f1(), f2(), max_iterations = 1,
  19. check = all.equal)
  20. #> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
  21. #> # A tibble: 2 × 6
  22. #> expression min median `itr/sec` mem_alloc `gc/sec`
  23. #> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
  24. #> 1 f1() 81.3ms 81.3ms 12.3 25.3MB 0
  25. #> 2 f2() 25.1s 25.1s 0.0398 169.2MB 2.47
展开查看全部
hmtdttj4

hmtdttj44#

  1. library(dplyr)
  2. mode <- \(x) as.numeric(names(sort(-table(x)))[1])
  3. df |>
  4. summarize(L = mode(c_across(starts_with("L"))),
  5. S = mode(c_across(starts_with("S"))), .by = ID)

对于每个IDc_across将向用户定义的函数mode传递一个数字向量,该函数将返回该向量中最常出现的数字。

输出

  1. ID L S
  2. 1 T1 0 2
  3. 2 T2 0 2
  4. 3 T3 0 2
  5. 4 T4 0 1
  6. 5 T5 0 2
  7. 6 T6 0 2
  8. 7 T7 0 2
  9. 8 T8 0 0
  10. 9 T9 0 2
展开查看全部

相关问题