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(只要因子级别按该顺序排列)。