web-dev-qa-db-ja.com

ifelseにNAを含める方法は?

他の列の値の論理ステートメントに基づいて列IDを作成しようとしています。たとえば、次のデータフレームで

_test <- structure(list(time = c(10L, 20L, NA, 30L), type = structure(c(1L, 
2L, 3L, NA), .Label = c("A", "B", "C"), class = "factor"), ID = c(NA, 
"1", NA, NA)), .Names = c("time", "type", "ID"), row.names = c(NA, 
-4L), class = "data.frame")
_

のように見える

_    time    type
1   10      A
2   20      B
3   NA      C
4   30      NA
_

ID以外のすべてのtimeおよびNA以外のすべてのtypeに対して、1の値を含む新しい列Aを作成します。これには次のコードを使用しています。

_test$ID <- ifelse(is.na(test$time) | test$type == "A", NA, "1")
_

これは結果を次のように与えます

_    time    type    ID
1   10      A       NA
2   20      B       1
3   NA      C       NA
4   30      NA      NA
_

ただし、このコードは列NAtypeを無視するため、列NAの値はIDになります。これは1の値にする必要があるため、必要なソリューションは次のようになります。

_    time    type    ID
1   10      A       NA
2   20      B       1
3   NA      C       NA
4   30      NA      1
_

誰も私にこれをどうやってやるか教えてもらえますか?何らかの方法でis.na(test$type)の結果を変更してFALSEの代わりにTRUEを返すことができれば、これを既存のコードで動作させることができますが、どうすればよいかわかりません。または、既存のコードの構造を完全に変更する必要がありますか?助けてくれてありがとう!

29
Thomas

NAを別の値と実際に比較することはできないため、_==_を使用しても機能しません。以下を考慮してください。

_NA == NA
# [1] NA
_

比較を_==_から_%in%_に変更するだけです:

_ifelse(is.na(test$time) | test$type %in% "A", NA, "1")
# [1] NA  "1" NA  "1"
_

他の質問については、

何らかの方法でis.na(test$type)の結果を変更してFALSEの代わりにTRUEを返すことができれば、これを既存のコードで動作させることができますが、どうすればよいかわかりませんそれを行う。

_!_を使用して、結果を否定します。

_!is.na(test$time)
# [1]  TRUE  TRUE FALSE  TRUE
_
32

@AnandaMahtoは、これらの結果が得られる理由に対処し、必要なものを取得する最も明確な方法を提供しました。しかし、別のオプションは、==の代わりにidenticalを使用することです。

test$ID <- ifelse(is.na(test$time) | sapply(as.character(test$type), identical, "A"), NA, "1")

または、isTRUEを使用します。

test$ID <- ifelse(is.na(test$time) | Vectorize(isTRUE)(test$type == "A"), NA, "1")
5
Matthew Plourde

Ifelseステートメントで、NA値を比較ではNAではなくFALSEとして解釈するようにしたいようです。次の関数を使用してこの状況を処理するため、NAの状況を継続的に処理する必要はありません。

falseifNA <- function(x){
  ifelse(is.na(x), FALSE, x)
}

ifelse2 <- function(x, a, b){
  ifelse(falseifNA(x), a, b)
}

これらの機能を1つに組み合わせて、より効率的にすることもできます。したがって、必要な結果を返すには、次を使用できます。

test$ID <- ifelse2(is.na(test$time) | test$type == "A", NA, "1")
3
Englehas

だから、私はこの作品を聞く:

Data$X1<-as.character(Data$X1)
Data$GEOID<-as.character(Data$BLKIDFP00)
Data<-within(Data,X1<-ifelse(is.na(Data$X1),GEOID,Data$X2)) 

しかし、私はそれに断続的な幸運しかないと認めています。

1
Mox

Elseifを試すこともできます。

x <- 1
if (x ==1){
    print('same')
} else if (x > 1){
    print('bigger')
} else {
    print('smaller')
}
1
Mox