R dplyr,将 mutate 与 na.omit 一起使用会导致错误大小不兼容 (%d)

Posted

技术标签:

【中文标题】R dplyr,将 mutate 与 na.omit 一起使用会导致错误大小不兼容 (%d)【英文标题】:R dplyr, using mutate with na.omit causes error incompatible size (%d) 【发布时间】:2015-08-25 05:01:52 【问题描述】:

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

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

Error: incompatible size (%d), expecting %d (the group size) or 1

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

    Zip
1 02345
2 02201

我注意到当数据中有 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'] )

导致

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

    Zip   Town1
1 02345 Manomet
2 02201  Boston

对于 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'] )

导致

Error: incompatible size (%d), expecting %d (the group size) or 1

示例 2。我想去掉以下数据中 Town 列中出现的冗余州名。

         Town State
1   BOSTON MA    MA
2 NORTH AMAMS    MA
3  CHICAGO IL    IL

这就是我的做法: (1) 将 Town 中的字符串拆分为单词,例如第 1 行的“波士顿”和“MA”。 (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])

这会导致:

         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

含义:例如,第 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)]) 

结果:

Error: incompatible size (%d), expecting %d (the group size) or 1

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

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

结果:

         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

所以它是长度的 %d==1。有人可以在哪里出错吗?谢谢

【问题讨论】:

【参考方案1】:

你能直接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

(如果发生这种情况,这种方式也会在城镇后面加上逗号。)

注意:如果您在此处使用 ungroup()rowwise_df(原样),它也会擦除 tbl_df 类并输出一个直接的 data.frame,这对您的数据很好,但会破坏如果您不小心并且正在查看大量数据(正如我无数次所做的那样),您的屏幕。 (Github 引用 #936 和 #553。)

【讨论】:

非常感谢@r2evans! [, ] 是否表示可选的逗号 + 空格? [ ] 是否意味着可选? 方括号将空格和逗号组合在一个类中,表示“这些(两个)字符之一”,尽管它可以超过两个并且包括范围(例如 [A-Za-z0-9] 表示“一个大写或小写字母或数字”)。正则表达式是一门艺术,通常很难找到一个好的备忘单/参考。 Wikibooks-R 是一个很好的参考。 * 后面的任何内容都是可选的,例如方括号类 [, ]。它读作“0 或更多”。使用 + 改为使其“1 或更多”。它们都允许重复字符或字符类。 感谢 NB @r2evans,您是大专家!关于data.frame和tbl_df的显示差异我和你一起讨论 实际上@r2evans 如果 '*' 将 '[, ]' 设为可选,则会出现问题。想象一下马萨诸塞州的一个叫 PUMA 的小镇。 PUMA 中的 MA 将被删除。我猜正则表达式中的强制空格可以保证只删除一个单独的状态缩写词。

以上是关于R dplyr,将 mutate 与 na.omit 一起使用会导致错误大小不兼容 (%d)的主要内容,如果未能解决你的问题,请参考以下文章

R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量将异常离散编码转化为NA值

R dplyr mutate 条件 when_case 无法更新数据帧

R语言dplyr包使用mutate函数生成新的数据列(不改变原数据列)实战

R语言dplyr包使用dplyr函数使用group_by函数summarise函数和mutate函数计算分组占比实战

R语言dplyr包mutate_if函数修改所有满足条件的数据列的内容实战

R语言dplyr包mutate_at函数通过名称修改指定数据列的内容(使用统一的函数)实战