我学习了这种方法来计算新列的值,条件是现有列中的值。我实际上从早期的帖子中获取了这个以及其他一些令人难以置信的方便提示:What is the most useful R trick?。
mydf <- expand.grid(var1 = c('type1', 'type2', 'type3'), var2 = c(1, 2, 3))
mydf$var3 <- rnorm(dim(mydf)[1], mean=90, sd=10)
mydf$column2[mydf$var3 > 90] <- "big" #now my conditional replacement
效果很好,但是有一个令人担忧的评论“这里有一个小陷阱[等...]。如果df $ column1包含NA值,使用==进行子集将拉出任何等于x和任何NAs的值要避免这种情况,请使用“%in%”而不是“==”。还有另一条注释要避免使用na.omit。但是,我没有观察到这种行为:
mydf <- expand.grid(var1 = c('type1', 'type2', 'type3'), var2 = c(1, 2, 3))
mydf$var3 <- rnorm(dim(mydf)[1], mean=90, sd=10)
mydf$var3[3] <- 90
mydf$var3[4] <- NA
is.na(mydf$var3[4]) # True!
mydf$column4[mydf$var3 == 90] <- "exactly 90!" # possible unintended behavior w/ row 4?
mydf$column4[mydf$var3 > 90] <- "big"
mydf # if there is a trap shouldn't mydf$column4[4] == "exactly 90!" ?
当然我感兴趣的是正确编码并避免任何可能的错误,但是无法弄清楚如何使用na.omit明确地将NA分配给var3中存在NA的行,就像我们为此做的那样其他逻辑条件,如var3 == 90.问题:a)为什么我没有看到我们被警告的意外匹配,b)我将如何编码以明确避免使用is.na,c)是否有任何其他意外用这种方法注意的行为?
答案 0 :(得分:0)
我不清楚你在问什么。如果您可以提供第四列之后应该如何应用的示例,那肯定会有所帮助。
但是,我认为na.pass()
可能对你有用。 na.omit()
删除包含至少一个NA
的所有行,此处似乎不需要。
> np <- na.pass(mydf$var3)
#[1] 106.17409 88.48014 90.00000 NA 91.62274 91.75860
#[7] 85.91689 91.06369 100.20514
> mydf$var4 <- ifelse(np > 90, "big", ifelse(np == 90, "exact", ""))
#[1] "big" "" "exact" NA "big" "big" "" "big" "big"
答案 1 :(得分:0)
是和否。陷阱是当您对data.frame进行子集时,也会返回NAs。但是,你并没有这么做,因为mydf$var3 == 90
返回逻辑向量而不是数据框的子集,任何TRUE都被“正好90”替换。而False和NA则没有。
mydf$var3 == 90
[1] FALSE FALSE TRUE NA FALSE FALSE FALSE FALSE FALSE
答案 2 :(得分:0)
可能有帮助。你可以使用90
的非常狭窄的断点(如果允许的话)
mydf$var4 <- with(mydf,
as.character(cut(var3, breaks=c(-Inf, 89.999999,90.0001, Inf), labels=c("", "exactly 90!", "big"))) )
mydf
# var1 var2 var3 var4
#1 type1 1 103.34752 big
#2 type2 1 88.58128
#3 type3 1 90.00000 exactly 90!
#4 type1 2 NA <NA>
#5 type2 2 72.37580
#6 type3 2 83.34518
#7 type1 3 96.28078 big
#8 type2 3 88.91577
#9 type3 3 78.68584