R 在转换中使用switch语句

R 在转换中使用switch语句,r,switch-statement,R,Switch Statement,我有一个数据框,带有: Exposure Signal Noise ill ADC 201 0.01 185.0 0.6744 1 12 471 0.03 210.2 0.7683 4 12 101 0.01 218.2 0.8356 1 10 381 0.03 249.5 0.8609 4 10 1 0.01 258.4 0.8988 1 9 301 0.03 292.7 0.8326

我有一个数据框,带有:

    Exposure Signal  Noise ill ADC
201     0.01  185.0 0.6744   1  12
471     0.03  210.2 0.7683   4  12
101     0.01  218.2 0.8356   1  10
381     0.03  249.5 0.8609   4  10
1       0.01  258.4 0.8988   1   9
301     0.03  292.7 0.8326   4   9
其中,我想根据
ill
值将曝光乘以一个因子,后者为1、4或10

我尝试了以下方法:

df2 <- transform(df, Exposure = Exposure * switch ("ill", "1"=1, "4"=3, "10"=11.5)  )

df2
开关
在这里不是正确的选择-您需要对
ill
的所有值进行矢量化。你得到的是对字符值“ill”起作用的东西——它根本不看你的数据帧

这方面的线索包括:

> switch ("ill", "1"=1, "4"=3, "10"=11.5)
> 
不返回任何内容

> switch (df$ill, "1"=1, "4"=3, "10"=11.5)
Error in switch(df$ill, `1` = 1, `4` = 3, `10` = 11.5) : 
  EXPR must be a length 1 vector
错误,因为你给了它一个向量

我将为您的乘法创建一个查找表:

> map=data.frame(ill=c(1,4,10), factor=c(1,3,11.5))
> map
  ill factor
1   1    1.0
2   4    3.0
3  10   11.5
然后使用
dplyr
内部联接获取每行的系数:

> require(dplyr)
> df %>% inner_join(map)
Joining by: "ill"
    Exposure ill factor
1  0.3698771   4    3.0
2  0.4274825   4    3.0
3  0.4120654   1    1.0
4  0.3098392   4    3.0
5  0.3205585   4    3.0
6  0.5340227  10   11.5
7  0.6466888  10   11.5
8  0.1581114  10   11.5
9  0.2598404   1    1.0
10 0.3056725   4    3.0
然后添加一个mutate和一个select以获取您想要的:

> df %>% inner_join(map) %>% mutate(Exposure=Exposure*factor) %>% select(-factor)
Joining by: "ill"
    Exposure ill
1  1.1096313   4
2  1.2824476   4
3  0.4120654   1
4  0.9295175   4
5  0.9616755   4
6  6.1412607  10
7  7.4369216  10
8  1.8182816  10
9  0.2598404   1
10 0.9170176   4

switch
在这里不是正确的选择-您需要对
ill
的所有值进行矢量化。你得到的是对字符值“ill”起作用的东西——它根本不看你的数据帧

这方面的线索包括:

> switch ("ill", "1"=1, "4"=3, "10"=11.5)
> 
不返回任何内容

> switch (df$ill, "1"=1, "4"=3, "10"=11.5)
Error in switch(df$ill, `1` = 1, `4` = 3, `10` = 11.5) : 
  EXPR must be a length 1 vector
错误,因为你给了它一个向量

我将为您的乘法创建一个查找表:

> map=data.frame(ill=c(1,4,10), factor=c(1,3,11.5))
> map
  ill factor
1   1    1.0
2   4    3.0
3  10   11.5
然后使用
dplyr
内部联接获取每行的系数:

> require(dplyr)
> df %>% inner_join(map)
Joining by: "ill"
    Exposure ill factor
1  0.3698771   4    3.0
2  0.4274825   4    3.0
3  0.4120654   1    1.0
4  0.3098392   4    3.0
5  0.3205585   4    3.0
6  0.5340227  10   11.5
7  0.6466888  10   11.5
8  0.1581114  10   11.5
9  0.2598404   1    1.0
10 0.3056725   4    3.0
然后添加一个mutate和一个select以获取您想要的:

> df %>% inner_join(map) %>% mutate(Exposure=Exposure*factor) %>% select(-factor)
Joining by: "ill"
    Exposure ill
1  1.1096313   4
2  1.2824476   4
3  0.4120654   1
4  0.9295175   4
5  0.9616755   4
6  6.1412607  10
7  7.4369216  10
8  1.8182816  10
9  0.2598404   1
10 0.9170176   4

如前所述,
开关
不是矢量化的,另一个选项是使用
ifelse
(即使编写嵌套的
ifelse
)也不是很简单:


如前所述,
开关
不是矢量化的,另一个选项是使用
ifelse
(即使编写嵌套的
ifelse
)也不是很简单:


您不需要
开关
ifelse

df2 <- transform(df, 
        Exposure = Exposure * ifelse(ill== 1,1,
                                     ifelse(ill==4,3,
                                            ifelse(ill==10,11.5,1))))
transform(df, Exposure = Exposure * c(1, 3, 11.5)[ill / 4 + 1])
它是如何工作的

如果
ill==1
2.0
如果
ill==4
3.5
如果
ill==10
,则命令
ill/4+1
返回
1.25

这些值用于索引(
[]
)。因此,它们会自动转换为整数,即
1
2
3
。这些索引用于从向量
c(1,3,11.5)
中选择适当的值,您不需要
开关
如果其他

df2 <- transform(df, 
        Exposure = Exposure * ifelse(ill== 1,1,
                                     ifelse(ill==4,3,
                                            ifelse(ill==10,11.5,1))))
transform(df, Exposure = Exposure * c(1, 3, 11.5)[ill / 4 + 1])
它是如何工作的

如果
ill==1
2.0
如果
ill==4
3.5
如果
ill==10
,则命令
ill/4+1
返回
1.25

这些值用于索引(
[]
)。因此,它们会自动转换为整数,即
1
2
3
。这些索引用于从向量
c(1,3,11.5)
中选择适当的值。我认为最简单的方法是使用
sapply

df2 <- transform (df, Exposure = Exposure * sapply(as.character(ill), switch, "1" = 1, "4"=3, "10" = 11.5))

df2我认为最简单的方法是使用
sapply

df2 <- transform (df, Exposure = Exposure * sapply(as.character(ill), switch, "1" = 1, "4"=3, "10" = 11.5))

df2谢谢!不太难看,虽然真正的开关会干净得多,谢谢!不太难看,虽然真正的开关会更干净谢谢你的解释,但是我找到了agstudy的解决方案cleaner@CharlesB这里可能更干净,但是如果你有更多的条件,我也会使用一个查找表(就像这里公开的答案,但是使用dplyr)。当查找表中有20个值且缩进将进入下一个房间时,您不会这么说!:)谢谢你的解释,不过我找到了agstudy的解决方案cleaner@CharlesB这里可能更干净,但是如果你有更多的条件,我也会使用一个查找表(就像这里公开的答案,但是使用dplyr)。当你的查找表中有20个值,并且缩进将进入下一个房间时,你不会这么说吧!:)但是如果你这样做了,你需要在你的代码中有一个严肃的评论来解释它的作用#脆弱性一个类似的技巧是将
ill
数字转换为一个因子,然后转换为数字,然后索引-因此“1”变为1,“4”变为2,“10”变为3(只要因子级别按该顺序排列)。但是如果你这样做,你需要在代码中认真地注释它的作用#一个类似的技巧是将
ill
数字转换为一个因子,然后转换为数字,然后索引-因此“1”变为1,“4”变为2,“10”变为3(只要因子级别按该顺序排列)。