[英]Using case_when() within mutate() to create levels for a factor variable
[英]dplyr - names of levels of factor not being passed properly within mutate when using rowwise()
首先,我对R非常陌生,我知道自己可能犯了一个明显的错误,已经寻找了答案,但是也许我在寻找错误的东西。
我正在尝试基于该行的内容应用函数以将新列添加到数据框。 但是在我看来,当使用rowwise
时, mutate
函数中的行中的值未正确处理。 我试图创建一个玩具示例来演示我的问题。
library(dplyr)
x<-c("A,"B")
y<-c(1,2)
df<-data.frame(x,y)
然后我有一个函数来创建一个新的列称为z
这增加了1到y
如果值x
是"A"
,并增加了2至y
如果值x
是"B"
。 请注意,我添加了print(x)
来显示正在发生的事情。
calculatez <- function(x,y){
print(x)
if(x == "A"){
return (y+1)
}
else{
return(y+2)
}
}
然后,我尝试使用mutate
:
df %>%
rowwise() %>%
mutate(z = calculatez(x,y))
我得到以下内容,两行都添加了2,而不是第一行添加了1,并且已将"A"
和"B"
作为1
和2
传递给函数。
[1] 1
[1] 2
Source: local data frame [2 x 3]
Groups:
x y z
1 A 1 3
2 B 2 4
如果我删除rowwise()
函数,则似乎正确传递了"A"
和"B"
,但是显然我没有得到正确的结果。
df %>%
mutate(z = calculatez(x,y))
[1] A B
Levels: A B
x y z
1 A 1 2
2 B 2 3
Warning message:
In if (x == "A") { :
the condition has length > 1 and only the first element will be used
如果我尝试不编写自己的函数就可以使它工作,那么我就不会收到有关条件长度的错误消息。 所以我认为我不正确理解rowwise()
在做什么。
df %>%
mutate(z = ifelse(x=="A",y+1,y+2))
x y z
1 A 1 2
2 B 2 4
但是我希望能够使用自己的函数,因为在我的实际应用程序中,条件更加复杂,并且在mutate
函数中使用大量嵌套的ifelse
函数将很难读取。
我可以通过将条件更改为if(x==1)
来解决问题,但这会使我的代码难以理解。
我不想浪费您的时间,如果我缺少明显的东西,对不起。 关于我要去哪里的任何提示?
您可以将rowwise
与do
rowwise
使用
df %>%
rowwise() %>%
do(data.frame(., z= calculatez(.$x, .$y)))
给出输出
x y z
#1 A 1 2
#2 B 2 4
或者您可以这样做:
df %>%
group_by(N=row_number()) %>%
mutate(z=calculatez(x,y))%>%
ungroup() %>%
select(-N)
使用其他数据集:
df <- structure(list(x = structure(c(1L, 1L, 2L, 2L, 2L), .Label = c("A",
"B"), class = "factor"), y = c(1, 2, 1, 2, 1)), .Names = c("x",
"y"), row.names = c(NA, -5L), class = "data.frame")
运行上面的代码将给出:
# x y z
#1 A 1 2
#2 A 2 3
#3 B 1 3
#4 B 2 4
#5 B 1 3
如果您使用的是data.table
library(data.table)
setDT(df)[, z := calculatez(x,y), by=seq_len(nrow(df))]
df
# x y z
# 1: A 1 2
# 2: A 2 3
# 3: B 1 3
# 4: B 2 4
# 5: B 1 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.