R dplyr,使用带有na.omit的mutate导致错误不兼容的大小(%d)

YJZ*_*YJZ 6 r dplyr

我正在做数据清理.我在Dplyr中使用mutate很多,因为它逐步生成新的列,我可以很容易地看到它是如何进行的.

以下是我遇到此错误的两个示例

Error: incompatible size (%d), expecting %d (the group size) or 1
Run Code Online (Sandbox Code Playgroud)

示例1:从邮政编码获取城镇名称.数据就像这样:

    Zip
1 02345
2 02201
Run Code Online (Sandbox Code Playgroud)

我注意到当数据中包含NA时,它不起作用.

没有NA它有效:

library(dplyr)
library(zipcode)
data(zipcode)

test = data.frame(Zip=c('02345','02201'),stringsAsFactors=FALSE)

test %>%
  rowwise() %>%
  mutate( Town1 = zipcode[zipcode$zip==na.omit(Zip),'city'] )
Run Code Online (Sandbox Code Playgroud)

导致

Source: local data frame [2 x 2]
Groups: <by row>

    Zip   Town1
1 02345 Manomet
2 02201  Boston
Run Code Online (Sandbox Code Playgroud)

使用NA它不起作用:

library(dplyr)
library(zipcode)
data(zipcode)

test = data.frame(Zip=c('02345','02201',NA),stringsAsFactors=FALSE)

test %>%
  rowwise() %>%
  mutate( Town1 = zipcode[zipcode$zip==na.omit(Zip),'city'] )
Run Code Online (Sandbox Code Playgroud)

导致

Error: incompatible size (%d), expecting %d (the group size) or 1
Run Code Online (Sandbox Code Playgroud)

例2.我想摆脱以下数据中Town列中出现的冗余状态名称.

         Town State
1   BOSTON MA    MA
2 NORTH AMAMS    MA
3  CHICAGO IL    IL
Run Code Online (Sandbox Code Playgroud)

我就是这样做的:(1)将Town中的字符串拆分成单词,例如'BOSTON'和'MA'表示第1行.(2)看看这些单词中是否有任何一行符合该行的状态(3)删除匹配的单词

library(dplyr)
test = data.frame(Town=c('BOSTON MA','NORTH AMAMS','CHICAGO IL'), State=c('MA','MA','IL'), stringsAsFactors=FALSE)

test %>%
  mutate(Town.word = strsplit(Town, split=' ')) %>%
  rowwise() %>% # rowwise ensures every calculation only consider currect row
  mutate(is.state = match(State,Town.word ) ) %>%
  mutate(Town1 = Town.word[-is.state])
Run Code Online (Sandbox Code Playgroud)

这导致:

         Town State Town.word is.state   Town1
1   BOSTON MA    MA  <chr[2]>        2  BOSTON
2 NORTH AMAMS    MA  <chr[2]>       NA      NA
3  CHICAGO IL    IL  <chr[2]>        2 CHICAGO
Run Code Online (Sandbox Code Playgroud)

含义:例如,第1行显示is.state == 2,表示Town中的第二个单词是州名.摆脱那项工作后,Town1是正确的城镇名称.

现在我想在第2行修复NA,但添加na.omit会导致错误:

test %>%
  mutate(Town.word = strsplit(Town, split=' ')) %>%
  rowwise() %>% # rowwise ensures every calculation only consider currect row
  mutate(is.state = match(State,Town.word ) ) %>%
  mutate(Town1 = Town.word[-na.omit(is.state)]) 
Run Code Online (Sandbox Code Playgroud)

结果是:

Error: incompatible size (%d), expecting %d (the group size) or 1
Run Code Online (Sandbox Code Playgroud)

我检查了数据类型和大小:

test %>%
  mutate(Town.word = strsplit(Town, split=' ')) %>%
  rowwise() %>% # rowwise ensures every calculation only consider currect row
  mutate(is.state = match(State,Town.word ) ) %>%
  mutate(length(is.state) ) %>%       
  mutate(class(na.omit(is.state)))
Run Code Online (Sandbox Code Playgroud)

结果是:

         Town State Town.word is.state length(is.state) class(na.omit(is.state))
1   BOSTON MA    MA  <chr[2]>        2                1                  integer
2 NORTH AMAMS    MA  <chr[2]>       NA                1                  integer
3  CHICAGO IL    IL  <chr[2]>        2                1                  integer
Run Code Online (Sandbox Code Playgroud)

所以它的长度为%d = 1.有人哪里错了?谢谢

r2e*_*ans 3

你能把sub它说出来吗?

test %>%
    rowwise() %>%
    mutate(Town=sub(sprintf('[, ]*%s$', State), '', Town))
## Source: local data frame [3 x 2]
## Groups: <by row>
##
##          Town State
## 1      BOSTON    MA
## 2 NORTH AMAMS    MA
## 3     CHICAGO    IL
Run Code Online (Sandbox Code Playgroud)

(如果发生这种情况,这种方式也会捕获城镇后面的逗号。)

注意:如果你ungroup()在这里使用 a rowwise_df(就像这样),它也会擦除tbl_df类并输出一个直接的 data.frame,这对你的数据来说很好,但如果你不小心并且正在查看,则会破坏你的屏幕大量数据(就像我已经做过无数次一样)。(Github 参考号#936#553。)