下面是我的数据框。
df1<-data.frame(month=c("march", "april"), apple=c(1,NA), peach=c(10,NA))
df2<-data.frame(month=c("march", "april"), apple=c(5,3), peach=c(NA,NA))
我希望R执行以下操作:
像这样:
我尝试了df1-df2
,但是两个数据帧都具有NA的位置被NA填充。
然后我尝试使用apply函数,但无法真正弄清楚该怎么做...
您能帮我吗?
答案 0 :(得分:1)
我认为您正在寻找类似的东西
```{r}
df1<-data.frame(month=c("march", "april"), apple=c(1,NA), peach=c(10,NA))
df2<-data.frame(month=c("march", "april"), apple=c(5,3), peach=c(NA,NA))
myconditions <- function(a, b) {
if (is.na(a)) {
if (is.na(b)) {
"both"
} else {
"first"
}
} else {
if(is.na(b)) {
"second"
} else {
a - b
}
}
}
df1$apple[match(df2$month,df1$month)] <- mapply(myconditions,df1$apple,df2$apple)
df1$peach[match(df2$month,df1$month)] <- mapply(myconditions,df1$peach,df2$peach)
```
结果矩阵将在df1中。
我们首先从用户定义的函数中定义的逻辑开始,然后将其应用于要对其执行操作的向量,因此使用apply可以使您处在正确的轨道上。
正如其他人所提到的,您正在混合字符串和整数,因此列的数据类型是字符向量,这可能不是您的目标。
答案 1 :(得分:1)
@Shree的评论是绝对正确的:返回帧时,不要期望-4
值是一个数字(实际上是"-4"
。我将假设还有其他内容需要在这里发生,所以这是您认为需要的解决方案:-)
func <- function(a,b) {
naa <- is.na(a)
nab <- is.na(b)
ifelse(naa,
ifelse(nab, "both", "first"),
ifelse(nab, "second", a-b))
}
mapply(func, df1[2:3], df2[2:3], SIMPLIFY=FALSE)
# $apple
# [1] "-4" "first"
# $peach
# [1] "second" "both"
我并不总是对嵌套ifelse
感到满意,但这并不极端。对于dplyr::case_when
,这可能是一个更好的机会,也许是以后的练习。
这可以直接应用于框架,例如:
df0 <- df1
df0[2:3] <- mapply(func, df1[2:3], df2[2:3], SIMPLIFY=FALSE)
df0
# month apple peach
# 1 march -4 second
# 2 april first both
但是(再次)如@Shree前面所述,您那里没有数字:
str(df0)
# 'data.frame': 2 obs. of 3 variables:
# $ month: Factor w/ 2 levels "april","march": 2 1
# $ apple: chr "-4" "first"
# $ peach: chr "second" "both"