我想将一个变量重新组合为一个新变量。
如果value为0,则新的也应为0。 如果值ist 999,则使其不存在,NA。 其他一切1
这是我的尝试:
id <- 1:10
variable <- c(0,0,0,1,2,3,4,5,999,999)
df <- data.frame(id,variable)
df$variable2 <-
if (df$variable == 0) {
df$variable2 = 0
} else if (df$variable == 999){
df$variable2 = NA
} else {
df$variable2 = 1
}
这是错误消息:
如果if(df $ variable == 0){:条件的长度> 1并且仅 将使用第一个元素
一个非常基本的问题,但我是一个基本用户。预先感谢!
答案 0 :(得分:3)
尝试ifelse
df$variable2 <- ifelse(df$variable == 999, NA, ifelse(df$variable > 0, 1, 0))
df
# id variable variable2
#1 1 0 0
#2 2 0 0
#3 3 0 0
#4 4 1 1
#5 5 2 1
#6 6 3 1
#7 7 4 1
#8 8 5 1
#9 9 999 NA
#10 10 999 NA
执行df$variable == 0
时,输出/ condition
为
#[1] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
在if(condition)
中,它应该是一个长度不是1的逻辑向量,请参见?"if"
。
例如,您可以避免使用ifelse
df$variable2 <- df$variable
df$variable2[df$variable2 == 999] <- NA
df$variable2[df$variable2 > 0] <- 1
答案 1 :(得分:2)
通过在子集符号内使用条件语句来避免同时使用if / else语句可能会更容易:
当df$variable
等于零时,将其更改为零
df$variable[df$variable==0] <- 0
当df$variable
等于999时,将其更改为NA
df$variable[df$variable==999] <- NA
当df$variable
大于0并且不等于NA时,将其更改为1
df$variable[df$variable>0 & is.na(df$variable) == 'FALSE'] <- 1
答案 2 :(得分:2)
好像您想重新编码变量。您可以使用sjmisc-package来执行此操作(以及其他数据/变量转换),对于您的情况,可以使用rec()
命令:
id <- 1:10
variable <- c(0,0,0,1,2,3,4,5,999,999)
df <- data.frame(id,variable)
library(sjmisc)
rec(df, variable, rec = c("0=0;999=NA;else=1"))
#> id variable variable_r
#> 1 1 0 0
#> 2 2 0 0
#> 3 3 0 0
#> 4 4 1 1
#> 5 5 2 1
#> 6 6 3 1
#> 7 7 4 1
#> 8 8 5 1
#> 9 9 999 NA
#> 10 10 999 NA
# or a single vector as input
rec(df$variable, rec = c("0=0;999=NA;else=1"))
#> [1] 0 0 0 1 1 1 1 1 NA NA
help-file中也有很多示例,您可以在RStudio-Cheatsheet collection(或direct PDF-download here)上找到一个sjmisc备忘单。
答案 3 :(得分:1)
df$variable2 <- sapply(df$variable,
function(el) if (el == 0) {0} else if (el == 999) {NA} else {1})
此一线代表您:
如果value为0,则新的也应为0。如果值999,则将其设为 失踪,不适用。其他一切1
好吧,它比@markus的第二个解决方案或@SPJ的解决方案(大多数是r-ish解决方案)要慢一些。
为什么要放弃ifelse
tt <- c(TRUE, FALSE, TRUE, FALSE)
a <- c("a", "b", "c", "d")
b <- 1:4
ifelse(tt, a, b) ## [1] "a" "2" "c" "4"
# totally perfect and as expected!
df <- data.frame(a=a, b=b, c=tt)
df$d <- ifelse(df$c, df$a, df$b)
## > df
## a b c d
## 1 a 1 TRUE 1
## 2 b 2 FALSE 2
## 3 c 3 TRUE 3
## 4 d 4 FALSE 4
######### This is wrong!! ##########################
## df$d is not [1] "a" "2" "c" "4"
## the problem is that
## ifelse(df$c, df$a, df$b)
## returns for each TRUE or FALSE the entire
## df$a or df$b intead of treating it like a vector.
## Since the last df$c is FALSE, df$b is returned
## Thus we get df$b for df$d.
## Quite an unintuitive behaviour.
##
## If one uses purely vectors, ifelse is fine.
## But actually df$c, df$a, df$b should be treated each like a vector.
## However, `ifelse` does not.
## No warnings that using `ifelse` with them will lead to a
## totally different behaviour.
## In my view, this is a design mistake of `ifelse`.
## Thus I decided myself to abandon `ifelse` from my set of R commands.
## To avoid that such kind of mistakes can ever happen.
#####################################################
正如@Parfait正确指出的那样,这是一种误解。 问题在于df $ a在数据框中被视为一个因素。
df <- data.frame(a=a, b=b, c=tt, stringsAsFactor = F)
df$d <- ifelse(df$c, df$a, df$b)
df
给出正确的结果。
a b c d
1 a 1 TRUE a
2 b 2 FALSE 2
3 c 3 TRUE c
4 d 4 FALSE 4
感谢@Parfait指出这一点! 奇怪的是我在最初的试用中没有意识到这一点。 但是,是的,您绝对正确!