首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用if-else逻辑计算数据帧中新向量的不同值

使用if-else逻辑计算数据帧中新向量的不同值
EN

Stack Overflow用户
提问于 2022-01-31 19:13:35
回答 3查看 39关注 0票数 1

这里有一个名为results的数据框架

代码语言:javascript
复制
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值,等于ab之和。

我需要创建向量a_prop_tweakb_prop_tweak并将它们附加到这个数据框架中。如果ab大于零,则这两个新变量是单向计算的(对于a,我用tot除以a,添加0.025;对于b,用tot除以b,减去0.025)。如果只有a为零(b_prop_tweak=b/ntota_prop_tweak=0),则计算值的方式有所不同。如果只有b为零,则应以另一种方式计算这两个变量(a_prop_tweak=a/ntotb_prop_tweak=0)。如果ab都是零,那么新变量也应该等于零。

下面是修改后的数据框架result应该是什么样子:

代码语言:javascript
复制
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_tweakb_prop_tweak等于0,否则tottot的总和将为1。

我为完成此任务而编写的不正确代码以一种我无意的方式工作:

代码语言:javascript
复制
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 (除了totab都为零时):

代码语言:javascript
复制
> 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

显然我想得不对。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-01-31 19:52:26

一种使用dplyr的解决方案,使用rowwisecase_when

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2022-01-31 19:29:27

有时,仔细地执行代码会有所帮助。您正在计算向量,而不是试图完成的每行计算行。通过这样做,您总是在if语句的这一部分结束:

代码语言:javascript
复制
else if(results$a == 0 && results$b > 0){
  results$a_prop_tweak <- 0
  results$b_prop_tweak <- results$b / results$tot

有很多方法来做你想做的事情,我稍后会试着发布其中一个。只是想让你看看到底出了什么问题。

代码语言:javascript
复制
> 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
票数 2
EN

Stack Overflow用户

发布于 2022-01-31 19:37:22

正如其他人所指出的,尝试测试像results$a>0这样的语句返回的内容。您将查看整个列,而不是一次只查看每一行。我可以通过将这些列细分为您感兴趣的特定情况来处理:

代码语言:javascript
复制
#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]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70931581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档