在没有复杂解释的情况下,让我们创建一个小的示例数据框:
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])
其中j
列A,
或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中的值?
谢谢。
答案 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.call
和pmax
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中的每一行的最大值。