计算df中每个元素的百分比值(基于最大值);但是在指定的列中

时间:2018-07-17 07:02:13

标签: r dataframe apply lapply

在没有复杂解释的情况下,让我们创建一个小的示例数据框:

A <- c(1,2,3,4)
B <- c(3,4,5,7)
C <- c(3,4,7,3)
D <- c(8,3,2,4)
df <- data.frame(A,B,C,D)

> df
  A B C D
1 1 3 3 8
2 2 4 4 3
3 3 5 7 2
4 4 7 3 4

我想使用apply函数计算A,B和C列中的百分比值。基于每行最大值的百分比值,换句话说:

%_to_be_calculated <- df[i,j] * 100 / max(df[i,1:3])

其中jA,B的{​​{1}}索引; C表中的后续行。

所需的输出:

i

我的解决方案

  A     B       C       D
1 33.33 100     100     8
2 50    100     100     3
3 42.85 71.42   100     2
4 57.14 100     42.85   4

它可以工作,但是它返回列表列表...我想拥有一个不错的df,能否给我一个提示,以替换当前df中的值?

谢谢。

3 个答案:

答案 0 :(得分:3)

有多种方法可以做到这一点。

正常的apply方式:

df[1:3] <- t(apply(df[1:3], 1, function(x) x/max(x) * 100))
df

#         A         B         C D
#1 33.33333 100.00000 100.00000 8
#2 50.00000 100.00000 100.00000 3
#3 42.85714  71.42857 100.00000 2
#4 57.14286 100.00000  42.85714 4

也可以通过以下方式完成:

df[1:3] <- df[1:3] * 100/apply(df[1:3], 1, max)

一种更快的方法是使用do.callpmax

df[1:3] <- df[1:3] * 100 /do.call(pmax, df[1:3])

答案 1 :(得分:1)

使用data.table:

df <- data.table(A,B,C,D)
df[,
   c(
     lapply(.SD, function(x) x/do.call(pmax,.SD[,.(A,B,C)])*100),
     D=list(D)
     ),
   .SDcols=c('A','B','C')
   ]

答案 2 :(得分:1)

虽然我确实喜欢do.call() + pmax()解决方案---通常,当您遇到定义明确的问题时,最简单的解决方案是将其包装成循环,然后考虑如何进行优化。 / p>

df2 <- df
for (i in 1:nrow(df)) {
  mi <- max(df[i, 1:3])
  for (j in 1:3) {
    df2[i, j] <- df[i, j] * 100 / mi
  }
}
df2
         A         B         C D
1 33.33333 100.00000 100.00000 8
2 50.00000 100.00000 100.00000 3
3 42.85714  71.42857 100.00000 2
4 57.14286 100.00000  42.85714 4

这可以分解问题,您可以看到内部循环非常容易向量化:

for (i in 1:nrow(df)) {
  mi <- max(df[i, 1:3]) 
  df2[i, 1:3] <- df[i, 1:3] * 100 / mi
}

现在,您的问题是如何更有效地查找turns out many people have thought about before中的每一行的最大值。