R语言 添加列以指示每行中所选列的重复率

vohkndzv  于 2022-12-06  发布在  其他
关注(0)|答案(6)|浏览(178)

我有一个 Dataframe ,如下所示:

df <- data.frame(ID = c(1,2,3,4,5), 
                 Total = c(1,1,2,1,2), 
                 Ma = c(1,2,1,2,1), 
                 Mb = c(1,2,1,2,2), 
                 Md = c(1,2,1,2,1), 
                 Me = c(1,1,1,2,2))

我想添加一个列来指示最大重复率,从TotalMe列的每一行。它应该是这样的:

rep.rate = c(1,0.6,0.8,0.8,0.6)

这些值指示每行中五列中最常见值的重复率。

ct2axkht

ct2axkht1#

你可以试试,

apply(df[-1], 1, function(i)max(prop.table(table(i))))
#[1] 1.0 0.6 0.8 0.8 0.6
lskq00tm

lskq00tm2#

下面是一个更简单的dplyr解决方案,它不需要用户定义的函数:
第一个

ttygqcqt

ttygqcqt3#

library(dplyr)

df <- data.frame(ID = c(1,2,3,4,5), Total = c(1,1,2,1,2), Ma = c(1,2,1,2,1), Mb = c(1,2,1,2,2), Md = c(1,2,1,2,1), Me = c(1,1,1,2,2))

cat_mode <-
  function(x){
    
    cat_levels <- unique(x)
    
    out <- cat_levels[which.max(tabulate(match(x, cat_levels)))]
    
    return(out)
    
  }

df %>% 
  rowwise() %>% 
  mutate(rep.rate = sum(c_across(Total:Me) == cat_mode(c_across(Total:Me)),na.rm =TRUE)/5 )

# A tibble: 5 x 7
# Rowwise: 
     ID Total    Ma    Mb    Md    Me rep.rate
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>
1     1     1     1     1     1     1      1  
2     2     1     2     2     2     1      0.6
3     3     2     1     1     1     1      0.8
4     4     1     2     2     2     2      0.8
5     5     2     1     2     1     2      0.6
ar7v8xwq

ar7v8xwq4#

df <- data.frame(ID = c(1,2,3,4,5), Total = c(1,1,2,1,2), Ma = c(1,2,1,2,1), Mb = c(1,2,1,2,2), Md = c(1,2,1,2,1), Me = c(1,1,1,2,2))

library(dplyr, warn.conflicts = FALSE)

get_repeat_rate <- function(x){
  table <- table(x)
  props <- table/sum(table
  max_prop <- max(props)
  return(max_prop)
}

df |> 
  rowwise() |> 
  mutate(repeat_rate = get_repeat_rate(c_across(-ID)))

#> # A tibble: 5 × 7
#> # Rowwise: 
#>      ID Total    Ma    Mb    Md    Me repeat_rate
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
#> 1     1     1     1     1     1     1         1  
#> 2     2     1     2     2     2     1         0.6
#> 3     3     2     1     1     1     1         0.8
#> 4     4     1     2     2     2     2         0.8
#> 5     5     2     1     2     1     2         0.6

创建于2022年12月2日,使用reprex v2.0.2

kknvjkwl

kknvjkwl5#

解决此问题的步骤如下:

df%>%
rowwise()%>%
mutate(rep.rate=sum(across(Total:Me)== max(Total:Me))/5)

rowwise()使所有操作按行进行,然后使用mutate创建新列,如下所示:max(Total:Me)找到最大值。然后sum(across(Total:Me)== max)找到当前行中出现最大值的次数。然后我们将此数除以5,得到所需的比例。

dfddblmv

dfddblmv6#

如果列只接受2个值,如示例数据中所示:

0.5 + abs(rowMeans(df[,-1] == df[1, 2]) - 0.5)
#> [1] 1.0 0.6 0.8 0.8 0.6

如果它们的值超过2个,则使用matrixStats::rowTabulates的矢量化解决方案:

library(matrixStats)

rowMaxs(
  rowTabulates(
    matrix(
      match(
        unlist(df[,-1]),
        unique(unlist(df[,-1]))
      ), nrow(df)
    )
  )
)/(ncol(df) - 1)
#> [1] 1.0 0.6 0.8 0.8 0.6

相关问题