dplyr-使用rowwise()时,在mutate中未正确传递因子级别的名称
首先,我对R很陌生,我意识到我可能犯了一个明显的错误,我已经在寻找答案,但也许我在寻找错误的东西 我试图应用一个函数,根据该行的内容向数据帧添加一个新列。但在我看来,在使用dplyr-使用rowwise()时,在mutate中未正确传递因子级别的名称,r,dplyr,R,Dplyr,首先,我对R很陌生,我意识到我可能犯了一个明显的错误,我已经在寻找答案,但也许我在寻找错误的东西 我试图应用一个函数,根据该行的内容向数据帧添加一个新列。但在我看来,在使用rowwise时,mutate函数未正确处理行中的值。我试图创建一个玩具示例来演示我的问题 library(dplyr) x<-c("A,"B") y<-c(1,2) df<-data.frame(x,y) 然后我尝试使用mutate: df %>% rowwise() %>%
rowwise
时,mutate
函数未正确处理行中的值。我试图创建一个玩具示例来演示我的问题
library(dplyr)
x<-c("A,"B")
y<-c(1,2)
df<-data.frame(x,y)
然后我尝试使用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
函数将很难读取
如果(x==1),我可以通过将条件更改为来绕过这个问题,但这会使我的代码难以理解
我不想浪费你的时间,如果我遗漏了一些明显的东西,我很抱歉。有关于我哪里出错的提示吗?您可以使用行方式和执行
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")
如果您使用的是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
谢谢,太好了。我现在知道如何得到我想要的。我以前没有遇到过do
,所以我会仔细阅读。但是我想我认为rowwise
相当于groupby(N=row\u number())
。就我的一般理解而言,你知道为什么我的第一次尝试没有成功吗?@techb1234根据?rowwise()的帮助页,当你创建列表变量时,“rowwise”用于“do”的结果。
出于某种原因,当你将mutate
与row_-wise()组合时只有calculatez
中的else
循环被执行。是的,因为出于某种原因,x
的值被传递为1
或2
而不是“A”
或“B”
,因此我的if(x==“A”)
条件总是false。但是谢谢你在帮助页面上给我指点,看起来rowwise
只适用于do
。很高兴知道。我现在已经在我的真实数据集(大约54k行)上测试了rowwise()%%>%do(…
和groupby(N=row\u number())%%>%mutate(…
解决方案)“<代码>突变< /COD>解决方案需要几秒钟的时间。<代码> do/Cux>解决方案大约需要3分钟!我猜这是因为<代码>突变代码< /COD>正在调用C++代码和<代码> do/Cuth>正在调用R代码。@ TeCB1234,这是我的新信息。谢谢。您可能需要查看源代码。您测试过“代码>数据吗?表< /代码”>解决方案?我想这比其他方法要快。
# x y z
#1 A 1 2
#2 A 2 3
#3 B 1 3
#4 B 2 4
#5 B 1 3
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