R语言 获取行中第一次出现的最频繁值的列名

s4chpxco  于 2023-03-20  发布在  其他
关注(0)|答案(4)|浏览(174)

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

week_0 <- c(5,0,1,0,0,1)
week_1 <- c(5,0,4,0,2,1)
week_2 <- c(5,0,4,0,8,1)
week_3 <- c(5,0,4,0,8,3)
week_4 <- c(1,0,4,0,8,3)
week_5 <- c(1,0,4,0,8,3)
week_6 <- c(1,0,4,0,1,3)
week_7 <- c(1,0,4,0,1,3)
week_8 <- c(1,0,6,0,3,4)
week_9 <- c(2,4,6,7,3,4)
week_10 <- c(2,4,6,7,3,4)
Participant <- c("Lion","Cat","Dog","Snake","Tiger","Mouse")
test_data <- data.frame(Participant,week_0,week_1,week_2,week_3,week_4,week_5,week_6,week_7,week_8,week_9,week_10)

> test_data

    Participant week_0 week_1 week_2 week_3 week_4 week_5 week_6 week_7 week_8 week_9 week_10
1        Lion      5      5      5      5      1      1      1      1      1      2       2
2         Cat      0      0      0      0      0      0      0      0      0      4       4
3         Dog      1      4      4      4      4      4      4      4      6      6       6
4       Snake      0      0      0      0      0      0      0      0      0      7       7
5       Tiger      0      2      8      8      8      8      1      1      3      3       3
6       Mouse      1      1      1      3      3      3      3      3      4      4       4

我想确定一行中出现次数比其他值多的值。例如,对于第一行,该值为1。对于第一行,我想返回的输出为week_4。对于第二行,出现次数比其他值多的值为0。我想返回的输出为week_0,依此类推。因此,最终结果应为:week_4week_0week_1week_0week_2week_3。我必须用途:

apply(test_data, 1, function(x) names(which.max(table(x))))

但是我没有得到我想要的结果。有什么建议吗?

fcg9iug3

fcg9iug31#

dplyradd_count + slice_maxdplyr解决方案:

library(dplyr)

test_data %>%
  tidyr::pivot_longer(starts_with('week')) %>%
  add_count(Participant, value) %>%
  slice_max(n, by = Participant, with_ties = FALSE)

# # A tibble: 6 × 4
#   Participant name   value     n
#   <chr>       <chr>  <dbl> <int>
# 1 Lion        week_4     1     5
# 2 Cat         week_0     0     9
# 3 Dog         week_1     4     7
# 4 Snake       week_0     0     9
# 5 Tiger       week_2     8     4
# 6 Mouse       week_3     3     5

如果存在“连接”,并且您希望在输出中包括所有连接:

test_data %>%
  tidyr::pivot_longer(starts_with('week')) %>%
  add_count(Participant, value) %>%
  slice_max(n, by = c(Participant, value), with_ties = FALSE) %>%
  slice_max(n, by = Participant)
w51jfk4q

w51jfk4q2#

尝试使用collapse中的fmode

library(collapse)
names(test_data)[-1][max.col(test_data[-1] == dapply(test_data[-1], 
    MARGIN = 1, fmode), "first")]
  • 输出
[1] "week_4" "week_0" "week_1" "week_0" "week_2" "week_3"
9cbw7uwe

9cbw7uwe3#

您的代码是很好的第一步,您可以使用结果match()它在行中的第一个位置,然后使用此位置索引列名称:

apply(test_data[, -1], 1, function(x) {
  val <- names(which.max(table(x)))
  names(test_data)[-1][[match(val, x)]]
})
# "week_4" "week_0" "week_1" "week_0" "week_2" "week_3"

注意我使用test_data[, -1]来排除Participant列;否则,如果没有出现多次的值,代码将返回参与者名称,这可能不是您想要的。

r1zhe5dt

r1zhe5dt4#

首先定义一个函数来求向量的众数:

Mode <- \(x) names(sort(-table(x)))[1]

Reference
困难的部分已经完成,现在使用dplyr的rowwise()c_across()

library(dplyr)

test_data %>%
  rowwise() %>%
  mutate(
    m = {
      x <- c_across(week_0:week_10) # get row as a vector
      names(x) <- names(test_data)[-1]
      index <- which(x == Mode(x))[1] # first occurence of mode in 'x'
      names(x)[index]
    }
  )

相关问题