我有一个数据框,我需要根据其他两个变量的值创建一个新变量。结果不符合我的期望。这就是我所拥有的:
d <- data.frame(
customer = rep(c("a","b"),3),
prod1 = c("tea", "gum", "candy", "tea","snack", "bar"),
prod2 = c(NA, NA, "juice", NA,NA,"cocoa")
)
d <- d[order(d$customer),]
> d
customer prod1 prod2
1 a tea <NA>
3 a candy juice
5 a snack <NA>
2 b gum <NA>
4 b tea <NA>
6 b bar cocoa
我想创建另一个变量,只有当!is.na(prod2)为真时才接受prod2的值,否则取值prod1。我尝试了两种方法并创建了两个不同的变量来比较结果:
ifelse(!is.na(d$prod2),
d$products1 <- d$prod2, d$products1 <- d$prod1)
d$products2[is.na(d$prod2)] <- d$prod1[is.na(d$prod2)]
d$products2[!is.na(d$prod2)] <- d$prod2[!is.na(d$prod2)]
我明白了:
> d
customer prod1 prod2 products1 products2 i.wanted
1 a tea <NA> tea 5 tea
3 a candy juice candy 2 juice
5 a snack <NA> snack 4 snack
2 b gum <NA> gum 3 gum
4 b tea <NA> tea 5 tea
6 b bar cocoa bar 1 cocoa
我想要的是列i.wanted但不是我得到的。 ifelse条件通过简单地从prod1获取值而不从prod2获取任何值来创建products1。第二种方法返回数字向量。
任何帮助表示赞赏!!!
答案 0 :(得分:1)
这可能是因为您将一个TRUE / FALSE值向量传递给ifelse函数。如果您使用多个逻辑值的变量进行条件分支,那么R不会喜欢它 - 因为哪个是它应该考虑的那个?通常它会假设向量中的第一个TRUE / FALSE值并给出警告。无论如何,这是使用apply函数执行此操作的一种方法:
d$i.wanted <- apply(d, 1, function(x){
if(!is.na(x[3])){
return(x[3])
} else {
return(x[2])
}
})
这里我逐行遍历d,并检查第三个变量,即prod2列中的值是否不是na,如果是,则返回。如果是NA,则返回第二个变量,即prod1的值。
此外,你的第二个解决方案实际上几乎是正确的,你推测索引是正确的,它可能给你问题的原因是它试图结合两个不同的因子变量,通过存储存储分类变量每个唯一值作为“级别”:
> d$prod1
[1] tea candy snack gum tea bar
Levels: bar candy gum snack tea
> d$prod2
[1] <NA> juice <NA> <NA> <NA> cocoa
Levels: cocoa juice
矢量索引那些级别,即d $ prod1是5,2,4,3 ......等等。因为酒吧是第5级,糖果是第2级,依此类推。 然后你可以开始明白为什么这可能在prod 1中存在问题,有5个级别1:5,而在prod2中,有两个级别1:2。在prod1中,任何“bar”都存储为1,但在prod2中,任何cocoa也存储为1.如果你修改了你编写的代码,将列视为字符串的向量而不是因子,那么你的两行将是工作:
d$products2[is.na(d$prod2)] <- as.character(d$prod1)[which(is.na(d$prod2))]
d$products2[!is.na(d$prod2)] <- as.character(d$prod2)[which(!is.na(d$prod2))]
希望有所帮助! 乙
答案 1 :(得分:0)
沃德感谢指出使用字符向量而不是默认因子。你的条件包括你的解决方案。但是,我尝试了不同的ifelse,这就是我发现的:
以下DID无法正常工作:
ifelse(!is.na(d$prod2),
d$products1 <- as.character(d$prod2),
d$products1 <- as.character(d$prod1))
这里有两个不同的条件产生了预期的结果:
d$products2 <- ifelse(!is.na(d$prod2),
d$products2 <- as.character(d$prod2),
d$products2 <- as.character(d$prod1))
d$products3 <- ifelse(!is.na(d$prod2),
as.character(d$prod2),
as.character(d$prod1))
从上面的结果中,我发现在需要ifelse条件和as.character之前我需要一个赋值。 d $ products1和d $ products2的创建方式完全相同,只是d $ products2在ifelse条件之前有一个赋值运算符。
这里是结果(产品2,3和4都很好):
> d
customer prod1 prod2 products1 products2 products3 products4
1 a tea <NA> tea tea tea tea
3 a candy juice candy juice juice juice
5 a snack <NA> snack snack snack snack
2 b gum <NA> gum gum gum gum
4 b tea <NA> tea tea tea tea
6 b bar cocoa bar cocoa cocoa cocoa