我正在尝试使用Unite函数将5列合并为一个新列。但是,所有行都包含许多NA值,创建的变量看起来像
Mother|NA|NA|NA|NA
NA|NA|Father|Mother|NA
Mother|Father|NA|Stepmother|NA
我尝试使用以下代码将它们团结在一起:
df2 <- df %>%
unite(Parent_full, Parent:Parent5, sep = "|", remove = TRUE, na.rm = TRUE)
但这给了我以下错误:
错误:TRUE
必须求出列的位置或名称,而不是逻辑向量
我也查看了论坛,发现unite的na.rm功能可能未激活?
有一些数据可以重新创建我的数据集
Name <- c('Paul', 'Edward', 'Mary')
Postalcode <- c('4732', '9045', '3476')
Parent <- c('Mother', 'NA', 'Mother')
Parent2 <- c('NA', 'NA', 'Father')
Parent3 <- c('NA', 'Father', 'NA')
Parent4 <- c('NA', 'Mother', 'Stepmother')
Parent5 <- c('NA', 'NA', 'NA')
df <- data.frame(Name, Postalcode, Parent, Parent2, Parent3, Parent4, Parent5)
很想知道没有NA的情况下如何统一我的专栏。
更新:
我现在已经更新了tidyr软件包,并在read_csv命令中添加了“ na = c(“,” NA“)”。
现在
df2 <- df %>%
unite(Parent_full, Parent:Parent5, sep = "|", remove = TRUE, na.rm = TRUE)
命令有效,但是由于某些原因,值末尾的NA保持不变。现在我的专栏看起来像这样:
Mother|NA
Father|Mother|NA
Mother|Father|Stepmother|NA
Does anyone know what went wrong now?
答案 0 :(得分:3)
您遇到了几个问题,
1) <textarea matInput id="content-textarea" placeholder="Required" [formControl]="formArray.controls[0]"></textarea>
不是真实的NA
(检查NA
)
2)您的列是因素
在构造数据框时,请使用is.na(df$Parent2)
stringsAsFactors = FALSE
然后替换df <- data.frame(Name, Postalcode, Parent, Parent2, Parent3, Parent4,
Parent5, stringsAsFactors = FALSE)
并使用NA
unite
如果数据已经加载,我们可以使用library(dplyr)
df %>%
na_if('NA') %>%
tidyr::unite(Parent_full, Parent:Parent5, sep = "|", na.rm = TRUE)
# Name Postalcode Parent_full
#1 Paul 4732 Mother
#2 Edward 9045 Father|Mother
#3 Mary 3476 Mother|Father|Stepmother
mutate_if
答案 1 :(得分:2)
您的主要问题是您尚未更新为tidyr
1.0。该错误消息是上一个版本最好使用输入na.rm = TRUE
处理的,因为该参数以前不存在。它认为您在...
中为其指定了命名参数。
具体来说,只需运行install.packages("tidyr")
,它就可以工作。您可能需要先重新启动R,所以tidyr
当前未加载。
如果缺少的值是"NA"
字符串,那么,正如Ronak指出的那样,您首先需要在它们上使用na_if()
。对我来说很奇怪,因为红色突出显示,您的初始代码块使其看起来像是适当的NA。但是,您的reprex代码具有'NA'
值,这些值肯定是字符串。无论如何,您说您正在从CSV读入,因此,运行CSV读取代码以便使用na
参数或类似参数正确读取NA会更加干净快捷。
对编辑的响应:这似乎是一个错误,没有正确删除联合字符串末尾的NA。好吧,无论如何,修复很容易,并且可能比我们能做的其他任何事情都要好:
df2 <- df %>%
unite(Parent_full, Parent:Parent5, sep = "|", na.rm = TRUE) %>%
mutate_at("Parent_full", . %>%
str_remove("(^|\\|)NA$") %>%
na_if(""))
这确保了两件事:1)仅由于unite()
除去字符串末尾的字母“ NA”,并且在它们前面加了一个管道(如果有) ;和2)如果此处的一行上没有非缺失值,则该值将是正确的NA,而不是"NA"
,""
或您拥有的东西,我认为这就是您想要的。
更新:我发现该错误适用于除NA之外不包含任何列的任何列,即na.rm = TRUE
仅从具有至少一个非缺失值的列中删除NA。我已提交了错误报告:https://github.com/tidyverse/tidyr/issues/765
但是,鉴于此,最佳解决方案可能只是删除所有事先都为NA的列。但是,如果这是生产代码,那么这将变得非常棘手,因为您必须指定unite()
,以便在之前的步骤中删除任何甚至所有要合并的列时都不会中断。 >
更新2 :作为对错误报告的回应,问题实际上是,所有缺失的列都是逻辑。因此,这是最佳的解决方案:读取字符列,或在合并之前将其强制为字符。完整说明:
library(tidyverse)
Name <- c('Paul', 'Edward', 'Mary')
Postalcode <- c('4732', '9045', '3476')
Parent <- c('Mother', NA, 'Mother')
Parent2 <- c(NA, NA, 'Father')
Parent3 <- c(NA, 'Father', NA)
Parent4 <- c(NA, 'Mother', 'Stepmother')
Parent5 <- c(NA, NA, NA)
(df <- data.frame(Name, Postalcode, Parent, Parent2, Parent3, Parent4, Parent5))
#> Name Postalcode Parent Parent2 Parent3 Parent4 Parent5
#> 1 Paul 4732 Mother <NA> <NA> <NA> NA
#> 2 Edward 9045 <NA> <NA> Father Mother NA
#> 3 Mary 3476 Mother Father <NA> Stepmother NA
(df2 <- df %>%
mutate_at(vars(Parent:Parent5), as.character) %>%
unite(Parent_full, Parent:Parent5, sep = "|", na.rm = TRUE))
#> Name Postalcode Parent_full
#> 1 Paul 4732 Mother
#> 2 Edward 9045 Father|Mother
#> 3 Mary 3476 Mother|Father|Stepmother
由reprex package(v0.3.0)于2019-09-27创建
答案 2 :(得分:1)
unite()
(和na.rm = TRUE
)仅适用于字符列(据我所知)。帮助文档中并未明确指出这一点。
对于因子,它还会返回整数代码而不是因子级别-需要注意的事情。
数字:不会删除NA:
df <- data.frame("to.combine1" = c(NA, 1, 3),
"to.combine2" = c(2, NA, 3))
sapply(df, class) #not functional, just illustrative
#> to.combine1 to.combine2
#> "numeric" "numeric"
unite(df, "combined", to.combine1:to.combine2, sep="_", na.rm = TRUE)
#> combined
#> 1 NA_2
#> 2 1_NA
#> 3 3_3
因子:不会删除NA,而是使用整数代码而不是级别:
df <- data.frame("to.combine1" = as.character(c(NA, 1, "a")),
"to.combine2" = as.character(c(2, NA, "a")),
stringsAsFactors = TRUE)
sapply(df, class) #not functional, just illustrative
#> to.combine1 to.combine2
#> "factor" "factor"
unite(df, "combined", to.combine1:to.combine2, sep="_", na.rm = TRUE)
#> combined
#>1 NA_1
#>2 1_NA
#>3 2_2
字符:预期的行为
df <- data.frame("to.combine1" = as.character(c(NA, 1, "a")),
"to.combine2" = as.character(c(2, NA, "a")),
stringsAsFactors = FALSE)
sapply(df, class) #not functional, just illustrative
#>to.combine1 to.combine2
#>"character" "character"
unite(df, "combined", to.combine1:to.combine2, sep="_", na.rm = TRUE)
#> combined
#> 1 2
#> 2 1
#> 3 a_a
答案 3 :(得分:0)
您可以稍后使用类似的内容删除NA
df %>%
unite(Parent_full, Parent:Parent5, sep = "|", remove = TRUE) %>%
mutate(Parent_full = gsub("(?<![a-zA-Z])NA\\||\\|NA(?![a-zA-Z])|\\|NA$", '', Parent_full, perl = T))
Name Postalcode Parent_full
1 Paul 4732 Mother
2 Edward 9045 Father|Mother
3 Mary 3476 Mother|Father|Stepmother
它以空字符串替换字符串末尾的NA|
(不带字母)或|NA
(不带字母或|NA
)