将列粘贴在一起但忽略 NA
Paste together columns but ignore NAs
我想将多列粘贴在一起但忽略 NA。
这是 df 的外观以及我希望它的外观的基本工作示例。有人有什么建议吗?
df <- data.frame("col1" = c("A", NA, "B", "C"),
"col2" = c(NA, NA, NA, "E"),
"col3" = c(NA, "D", NA, NA),
"col4" = c(NA, NA, NA, NA))
df_fixed <- data.frame("col" = c("A", "D", "B", "C,E"))
我们可以使用 unite
可以有 na.rm
作为参数
library(tidyr)
library(dplyr)
df %>%
unite(col, everything(), na.rm = TRUE, sep=",")
-输出
col
1 A
2 D
3 B
4 C,E
或将 base R
与 do.call
和 trimws
一起使用
data.frame(col = trimws(do.call(paste, c(df, sep = ",")),
whitespace = "(?:,?NA,?)+"))
-输出
col
1 A
2 D
3 B
4 C,E
使用 paste
.
data.frame(col1=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
# col1
# 1 A
# 2 D
# 3 B
# 4 C,E
或没有apply
:
data.frame(col1=unname(as.list(as.data.frame(t(df))) |>
(\(x) sapply(x, \(x) paste(x[!is.na(x)], collapse=',')))()))
# col1
# 1 A
# 2 D
# 3 B
# 4 C,E
要添加为列,请使用 transform
。
transform(df, colX=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
# col1 col2 col3 col4 colX
# 1 A <NA> <NA> NA A
# 2 <NA> <NA> D NA D
# 3 B <NA> <NA> NA B
# 4 C E <NA> NA C,E
注意:其实,你也可以用na.omit
代替\(x) x[!is.na(x)]
,因为它的属性消失了;参见例如@G.格洛腾迪克的.
可能的基础 R 解决方案:
df2 <- data.frame(col=apply(df,1, function(x) paste0(na.omit(x), collapse = ",")))
df2
#> col
#> 1 A
#> 2 D
#> 3 B
#> 4 C,E
使用 na.omit 和 toString。没有使用包。
data.frame(col = apply(df, 1, function(x) toString(na.omit(x)))
## col
## 1 A
## 2 D
## 3 B
## 4 C, E
如果输出中的空格有问题,请使用其中之一而不是显示的匿名函数:
function(x) paste(na.omit(x), collapse = ",")
function(x) gsub(", ", ",", toString(na.omit(x)))
我想将多列粘贴在一起但忽略 NA。
这是 df 的外观以及我希望它的外观的基本工作示例。有人有什么建议吗?
df <- data.frame("col1" = c("A", NA, "B", "C"),
"col2" = c(NA, NA, NA, "E"),
"col3" = c(NA, "D", NA, NA),
"col4" = c(NA, NA, NA, NA))
df_fixed <- data.frame("col" = c("A", "D", "B", "C,E"))
我们可以使用 unite
可以有 na.rm
作为参数
library(tidyr)
library(dplyr)
df %>%
unite(col, everything(), na.rm = TRUE, sep=",")
-输出
col
1 A
2 D
3 B
4 C,E
或将 base R
与 do.call
和 trimws
data.frame(col = trimws(do.call(paste, c(df, sep = ",")),
whitespace = "(?:,?NA,?)+"))
-输出
col
1 A
2 D
3 B
4 C,E
使用 paste
.
data.frame(col1=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
# col1
# 1 A
# 2 D
# 3 B
# 4 C,E
或没有apply
:
data.frame(col1=unname(as.list(as.data.frame(t(df))) |>
(\(x) sapply(x, \(x) paste(x[!is.na(x)], collapse=',')))()))
# col1
# 1 A
# 2 D
# 3 B
# 4 C,E
要添加为列,请使用 transform
。
transform(df, colX=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
# col1 col2 col3 col4 colX
# 1 A <NA> <NA> NA A
# 2 <NA> <NA> D NA D
# 3 B <NA> <NA> NA B
# 4 C E <NA> NA C,E
注意:其实,你也可以用na.omit
代替\(x) x[!is.na(x)]
,因为它的属性消失了;参见例如@G.格洛腾迪克的
可能的基础 R 解决方案:
df2 <- data.frame(col=apply(df,1, function(x) paste0(na.omit(x), collapse = ",")))
df2
#> col
#> 1 A
#> 2 D
#> 3 B
#> 4 C,E
使用 na.omit 和 toString。没有使用包。
data.frame(col = apply(df, 1, function(x) toString(na.omit(x)))
## col
## 1 A
## 2 D
## 3 B
## 4 C, E
如果输出中的空格有问题,请使用其中之一而不是显示的匿名函数:
function(x) paste(na.omit(x), collapse = ",")
function(x) gsub(", ", ",", toString(na.omit(x)))