为了账号安全,请及时绑定邮箱和手机立即绑定

嵌套ifasser语句

嵌套ifasser语句

哔哔one 2019-07-06 17:48:21
嵌套ifasser语句我仍在学习如何将SAS代码转换为R,并收到警告。我需要弄清楚我在哪里犯错误。我想要做的是创建一个变量来总结和区分一个人口的三个状态:大陆,海外,外国人。我有一个包含两个变量的数据库:ID国籍:idnat(法语、外国人)、如果idnat那么法语是:身份证出生地:idbp(内地、殖民地、海外)我想总结一下idnat和idbp到一个名为idnat2:地位:K(内地、海外、外国人)所有这些变量都使用“字符类型”。第2栏预期的结果:   idnat     idbp   idnat21  french mainland mainland2  french   colony overseas3  french overseas overseas4 foreign      foreign  foreign下面是我想在R中翻译的SAS代码:if idnat = "french" then do;    if idbp in ("overseas","colony") then idnat2 = "overseas";    else idnat2 = "mainland";end;else idnat2 = "foreigner";run;以下是我在R中的尝试:if(idnat=="french"){     idnat2 <- "mainland"} else if(idbp=="overseas"|idbp=="colony"){     idnat2 <- "overseas"} else {     idnat2 <- "foreigner"}我收到这样的警告:Warning message:In if (idnat=="french") { :   the condition has length > 1 and only the first element will be used我被建议使用“嵌套”ifelse“相反,它的轻松,但得到更多的警告:idnat2 <- ifelse (idnat=="french", "mainland",         ifelse (idbp=="overseas"|idbp=="colony", "overseas")       )             else (idnat2 <- "foreigner")根据警告消息,长度大于1,因此只考虑第一个括号之间的内容。对不起,我不明白这个长度和这里有什么关系?有人知道我哪里错了吗?
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

尝试如下所示:

# some sample dataidnat <- sample(c("french","foreigner"),100,TRUE)idbp <- rep(NA,100)idbp[idnat=="french"]
 <- sample(c("mainland","overseas","colony"),sum(idnat=="french"),TRUE)# recodingout <- ifelse(idnat=="french" &
  !idbp %in% c("overseas","colony"), "mainland",
              ifelse(idbp %in% c("overseas","colony"),"overseas",
                     "foreigner"))cbind(idnat,idbp,out) # check result

您的困惑来自SAS和R如何处理if-etc结构。在R,ifelse没有向量化,这意味着它们检查单个条件是否为真(即,if("french"=="french")无法处理多个逻辑(即,if(c("french","foreigner")=="french")R给你收到的警告。

相比之下,ifelse是矢量化的,因此它可以接受向量(也称为输入变量),并测试每个元素的逻辑条件,就像您习惯于在SAS中那样。另一种让你头脑清醒的方法是用以下方法构建一个循环ifelse语句(就像您在这里开始做的那样),但是ifelse方法将更有效率,涉及的代码通常更少。


查看完整回答
反对 回复 2019-07-06
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

如果数据集包含许多行,则使用data.table而不是嵌套ifelse().


提供了下面的查找表


lookup

     idnat     idbp   idnat2

1:  french mainland mainland

2:  french   colony overseas

3:  french overseas overseas

4: foreign  foreign  foreign

和一个样本数据集


library(data.table)

n_row <- 10L

set.seed(1L)

DT <- data.table(idnat = "french",

                 idbp = sample(c("mainland", "colony", "overseas", "foreign"), n_row, replace = TRUE))

DT[idbp == "foreign", idnat := "foreign"][]

      idnat     idbp

 1:  french   colony

 2:  french   colony

 3:  french overseas

 4: foreign  foreign

 5:  french mainland

 6: foreign  foreign

 7: foreign  foreign

 8:  french overseas

 9:  french overseas

10:  french mainland

然后我们可以做一个加入时更新:


DT[lookup, on = .(idnat, idbp), idnat2 := i.idnat2][]

      idnat     idbp   idnat2

 1:  french   colony overseas

 2:  french   colony overseas

 3:  french overseas overseas

 4: foreign  foreign  foreign

 5:  french mainland mainland

 6: foreign  foreign  foreign

 7: foreign  foreign  foreign

 8:  french overseas overseas

 9:  french overseas overseas

10:  french mainland mainland


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 499 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信