我有一个数据框:
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
我希望将Exposure乘以一个因子,具体取决于ill
值,后者可以是1,4或10。
我尝试了以下内容:
df2 <- transform(df, Exposure = Exposure * switch ("ill", "1"=1, "4"=3, "10"=11.5) )
但我得到的只是df2$Exposure
中的NAs
我做错了什么?
答案 0 :(得分:3)
switch
在这里不是正确的事情 - 你需要为ill
的所有值进行矢量化的东西。你所得到的是对角色价值的影响&#34;生病&#34; - 它根本没有看你的数据框架!
这方面的线索包括:
> 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
答案 1 :(得分:2)
如上所述,switch
没有矢量化,另一种选择是使用ifelse
(即使编写嵌套的ifelse
也不是很简单):
df2 <- transform(df,
Exposure = Exposure * ifelse(ill== 1,1,
ifelse(ill==4,3,
ifelse(ill==10,11.5,1))))
这是首次尝试创建“矢量化开关”功能(该代码仅在OP情况下进行测试):
switch_v <-
function(expr,...){
cond <- list(...)
lefts <- as.numeric(names(cond))
values <- cond
for(i in seq_along(lefts))
expr[expr==lefts[i]] <- values[i]
unlist(expr)
}
现在您可以正常使用它switch
:
df <- transform(df,
Exposure2 = Exposure * switch_v(ill,"1"=1, "4"=3, "10"=11.5))
答案 2 :(得分:1)
您不需要switch
或ifelse
:
transform(df, Exposure = Exposure * c(1, 3, 11.5)[ill / 4 + 1])
它如何运作?
如果ill / 4 + 1
,则1.25
会返回ill == 1
,2.0
会返回ill == 4
,3.5
会返回ill == 10
。
这些值用于索引([]
)。因此,它们会自动转换为整数,即1
,2
和3
。这些索引用于从向量c(1, 3, 11.5)
中选择适当的值。
答案 3 :(得分:0)
我认为最简单的方法是使用sapply
df2 <- transform (df, Exposure = Exposure * sapply(as.character(ill), switch, "1" = 1, "4"=3, "10" = 11.5))