dplyr-使用rowwise()时,在mutate中未正确传递因子级别的名称

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() %>%

首先,我对R很陌生,我意识到我可能犯了一个明显的错误,我已经在寻找答案,但也许我在寻找错误的东西

我试图应用一个函数,根据该行的内容向数据帧添加一个新列。但在我看来,在使用
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