这里有一个名为results的数据框架
results <- data.frame(cbind(tot=c(3,4,3,2,1,1,3,0),
a=c(0,1,2,2,0,1,1,0),
b=c(3,3,1,0,1,0,2,0)))每一行包含一个tot值,等于a和b之和。
我需要创建向量a_prop_tweak和b_prop_tweak并将它们附加到这个数据框架中。如果a和b大于零,则这两个新变量是单向计算的(对于a,我用tot除以a,添加0.025;对于b,用tot除以b,减去0.025)。如果只有a为零(b_prop_tweak=b/ntot;a_prop_tweak=0),则计算值的方式有所不同。如果只有b为零,则应以另一种方式计算这两个变量(a_prop_tweak=a/ntot;b_prop_tweak=0)。如果a和b都是零,那么新变量也应该等于零。
下面是修改后的数据框架result应该是什么样子:
results <- data.frame(cbind(tot=c(3, 4, 3, 2, 1, 1, 3, 0),
a=c(0, 1, 2, 2, 0, 1, 1, 0),
b=c(3, 3, 1, 0, 1, 0, 2, 0),
a_prop_tweak=c(0, 0.275, 0.6916667, 1, 0, 1, 0.3583333, 0),
b_prop_tweak=c(1, 0.725, 0.3083333, 0, 1, 0, 0.6416667, 0)))请注意,除非a_prop_tweak和b_prop_tweak等于0,否则tot和tot的总和将为1。
我为完成此任务而编写的不正确代码以一种我无意的方式工作:
if(results$a > 0 && results$b > 0){
results$a_prop_tweak <- results$a / results$tot + 0.025
results$b_prop_tweak <- results$b / results$tot - 0.025
}else if(results$a > 0 && results$b == 0){
results$a_prop_tweak <- results$a / results$tot
results$b_prop_tweak <- 0
}else if(results$a == 0 && results$b > 0){
results$a_prop_tweak <- 0
results$b_prop_tweak <- results$b / results$tot
}else{
results$a_prop_tweak <- 0
results$b_prop_tweak <- 0
}下面是输出,它似乎正确地计算了b_prop_tweak (除了tot、a和b都为零时):
> results
tot a b a_prop_tweak b_prop_tweak ab_prop_chk
1 3 0 3 0 1.0000000 1
2 4 1 3 0 0.7500000 1
3 3 2 1 0 0.3333333 1
4 2 2 0 0 0.0000000 1
5 1 0 1 0 1.0000000 1
6 1 1 0 0 0.0000000 1
7 3 1 2 0 0.6666667 1
8 0 0 0 0 NaN 0显然我想得不对。有什么想法吗?
发布于 2022-01-31 19:52:26
一种使用dplyr的解决方案,使用rowwise和case_when
library(dplyr)
results %>%
rowwise() %>%
mutate( a_prop_tweak=case_when(
a > 0 & b > 0 ~ (a/tot) + 0.025,
a == 0 & b != 0 ~ 0,
a != 0 & b == 0 ~ a/tot,
a == 0 & b == 0 ~ 0 ),
b_prop_tweak=case_when(
a > 0 & b > 0 ~ (b/tot) - 0.025,
a == 0 & b != 0 ~ b/tot,
a != 0 & b == 0 ~ 0,
a == 0 & b == 0 ~ 0 ) ) %>%
ungroup()
# A tibble: 8 × 5
tot a b a_prop_tweak b_prop_tweak
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3 0 3 0 1
2 4 1 3 0.275 0.725
3 3 2 1 0.692 0.308
4 2 2 0 1 0
5 1 0 1 0 1
6 1 1 0 1 0
7 3 1 2 0.358 0.642
8 0 0 0 0 0发布于 2022-01-31 19:29:27
有时,仔细地执行代码会有所帮助。您正在计算向量,而不是试图完成的每行计算行。通过这样做,您总是在if语句的这一部分结束:
else if(results$a == 0 && results$b > 0){
results$a_prop_tweak <- 0
results$b_prop_tweak <- results$b / results$tot有很多方法来做你想做的事情,我稍后会试着发布其中一个。只是想让你看看到底出了什么问题。
> results$a
[1] 0 1 2 2 0 1 1 0
> results$b
[1] 3 3 1 0 1 0 2 0
> results$a > 0 && results$b
[1] FALSE
> results$a > 0 && results$b
[1] FALSE
> results$a == 0 && results$b > 0
[1] TRUE发布于 2022-01-31 19:37:22
正如其他人所指出的,尝试测试像results$a>0这样的语句返回的内容。您将查看整个列,而不是一次只查看每一行。我可以通过将这些列细分为您感兴趣的特定情况来处理:
#Create the data frame
results <- data.frame(cbind(tot=c(3,4,3,2,1,1,3,0),
a=c(0,1,2,2,0,1,1,0),
b=c(3,3,1,0,1,0,2,0)))
#create the new columns and initialize to 0
results$a_prop_tweak <- 0
results$b_prop_tweak <- 0
#Deal with cases where both a and b are >0
results$a_prop_tweak[results$a >0 & results$b >0] <- results$a[results$a >0 & results$b >0] /
results$tot[results$a >0 & results$b >0] +0.025
results$b_prop_tweak[results$a >0 & results$b >0] <- results$b[results$a >0 & results$b >0] /
results$tot[results$a >0 & results$b >0] -0.025
#If a>0 but b==0:
results$a_prop_tweak[results$a >0 & results$b == 0] <- results$a[results$a >0 & results$b == 0] /
results$tot[results$a >0 & results$b == 0]
#No need for a b_prop_tweak since it's already 0 by default
#If a==0 and b>0
results$b_prop_tweak[results$a == 0 & results$b > 0] <- results$b[results$a == 0 & results$b > 0] /
results$tot[results$a == 0 & results$b > 0]https://stackoverflow.com/questions/70931581
复制相似问题