在每一列中找到唯一的行并在 r 中标记它们
find unique rows in every column and mark them in r
我有一个包含 1000 行和几列的数据框,我想在其中找到唯一的行并标记每列是否具有唯一值。
例如,我有一个如下所示的数据框。
数据框:structure(list(X = c("Row1", "Row2", "Row3", "Row4", "Row5", "Row6", "Row7"), Col1 = c(0L, 1L, 1L, 0L, 1L, -1L, 0L), Col2 = c(1L, 0L, 1L, 1L, 1L, 0L, -2L), Col3 = c(-1L, 0L, 1L, 0L, 0L, 1L, 1L )), class = "data.frame", row.names = c(NA, -7L))
Col1 Col2 Col3
Row1 0 1 -1
Row2 1 0 0
Row3 1 1 1
Row4 0 1 0
Row5 1 1 0
Row6 -1 0 1
Row7 0 -2 1
我想获取以下数据框。
Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
Row1 0 1 -1 Col1 Col2 Col3
Row2 1 0 0 Col1 NA NA
Row3 1 1 1 NA NA NA
Row4 0 1 0 NA Col2 NA
Row5 1 1 0 NA NA NA
Row6 -1 0 1 Col1 Col2 Col3
Row7 0 -2 1 Col1 Col2 Col3
我已经尝试过 df=df[row.names(unique(df[,c("clo_2")])), c("clo_2")]
但那并不是真的 helps.I 希望有人对此有一个简单的解决方案。提前致谢。
这是一个给出逻辑值但不考虑列名的例子。如有必要,您可以轻松修改以提供向量的名称。它只是应用一个函数来逐行检查 。
df <- structure(list(Col1 = c(0, 1, 1, 0, 1, -1, 0),
Col2 = c(1, 0, 1, 1, 1, 0, -2),
Col3 = c(-1, 0, 1, 0, 0, 1, 1)),
row.names = c(NA, -7L),
class = c("tbl_df", "tbl", "data.frame"))
chk <- apply(df, 1, function(x) !x %in% x[duplicated(x)])
cbind(df, t(chk))
#> Col1 Col2 Col3 1 2 3
#> 1 0 1 -1 TRUE TRUE TRUE
#> 2 1 0 0 TRUE FALSE FALSE
#> 3 1 1 1 FALSE FALSE FALSE
#> 4 0 1 0 FALSE TRUE FALSE
#> 5 1 1 0 FALSE FALSE TRUE
#> 6 -1 0 1 TRUE TRUE TRUE
#> 7 0 -2 1 TRUE TRUE TRUE
我们可以使用 dplyr 和 rowwise()
:
library(dplyr)
df %>% rowwise %>%
mutate(across(starts_with('Col'), ~ sum(c_across(starts_with('Col')) == .x), .names = "{.col}_uni"),
across(ends_with('uni'), ~ifelse(.x==1, str_remove(deparse(substitute(.x)), '_uni$'), NA)))
# A tibble: 7 × 7
# Rowwise:
X Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
<chr> <int> <int> <int> <chr> <chr> <chr>
1 Row1 0 1 -1 Col1 Col2 Col3
2 Row2 1 0 0 Col1 NA NA
3 Row3 1 1 1 NA NA NA
4 Row4 0 1 0 NA Col2 NA
5 Row5 1 1 0 NA NA Col3
6 Row6 -1 0 1 Col1 Col2 Col3
7 Row7 0 -2 1 Col1 Col2 Col3
我还推荐@caldwellst 建议的更简单的“col_names-less”方法,我的回答中的简化代码是:
libarry(dplyr)
df %>% rowwise %>%
mutate(across(starts_with('Col'),
~sum(c_across(starts_with('Col')) == .x) == 1,
.names = "{.col}_uni"))
# A tibble: 7 × 7
# Rowwise:
X Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
<chr> <int> <int> <int> <lgl> <lgl> <lgl>
1 Row1 0 1 -1 TRUE TRUE TRUE
2 Row2 1 0 0 TRUE FALSE FALSE
3 Row3 1 1 1 FALSE FALSE FALSE
4 Row4 0 1 0 FALSE TRUE FALSE
5 Row5 1 1 0 FALSE FALSE TRUE
6 Row6 -1 0 1 TRUE TRUE TRUE
7 Row7 0 -2 1 TRUE TRUE TRUE
A base R 解决方案,按行应用
data.frame( dat, setNames( data.frame( t(apply( dat, 1, function(x){
tf=!duplicated(x, fromLast=F)&!duplicated(x, fromLast=T);
ifelse( tf,colnames(dat)[tf],NA) } ) )), paste0(colnames(dat),"_uni") ) )
Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
Row1 0 1 -1 Col1 Col2 Col3
Row2 1 0 0 Col1 <NA> <NA>
Row3 1 1 1 <NA> <NA> <NA>
Row4 0 1 0 <NA> Col2 <NA>
Row5 1 1 0 <NA> <NA> Col3
Row6 -1 0 1 Col1 Col2 Col3
Row7 0 -2 1 Col1 Col2 Col3
数据
dat <- structure(list(Col1 = c(0L, 1L, 1L, 0L, 1L, -1L, 0L), Col2 = c(1L,
0L, 1L, 1L, 1L, 0L, -2L), Col3 = c(-1L, 0L, 1L, 0L, 0L, 1L, 1L
)), class = "data.frame", row.names = c("Row1", "Row2", "Row3",
"Row4", "Row5", "Row6", "Row7"))
我有一个包含 1000 行和几列的数据框,我想在其中找到唯一的行并标记每列是否具有唯一值。
例如,我有一个如下所示的数据框。
数据框:structure(list(X = c("Row1", "Row2", "Row3", "Row4", "Row5", "Row6", "Row7"), Col1 = c(0L, 1L, 1L, 0L, 1L, -1L, 0L), Col2 = c(1L, 0L, 1L, 1L, 1L, 0L, -2L), Col3 = c(-1L, 0L, 1L, 0L, 0L, 1L, 1L )), class = "data.frame", row.names = c(NA, -7L))
Col1 Col2 Col3
Row1 0 1 -1
Row2 1 0 0
Row3 1 1 1
Row4 0 1 0
Row5 1 1 0
Row6 -1 0 1
Row7 0 -2 1
我想获取以下数据框。
Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
Row1 0 1 -1 Col1 Col2 Col3
Row2 1 0 0 Col1 NA NA
Row3 1 1 1 NA NA NA
Row4 0 1 0 NA Col2 NA
Row5 1 1 0 NA NA NA
Row6 -1 0 1 Col1 Col2 Col3
Row7 0 -2 1 Col1 Col2 Col3
我已经尝试过 df=df[row.names(unique(df[,c("clo_2")])), c("clo_2")]
但那并不是真的 helps.I 希望有人对此有一个简单的解决方案。提前致谢。
这是一个给出逻辑值但不考虑列名的例子。如有必要,您可以轻松修改以提供向量的名称。它只是应用一个函数来逐行检查
df <- structure(list(Col1 = c(0, 1, 1, 0, 1, -1, 0),
Col2 = c(1, 0, 1, 1, 1, 0, -2),
Col3 = c(-1, 0, 1, 0, 0, 1, 1)),
row.names = c(NA, -7L),
class = c("tbl_df", "tbl", "data.frame"))
chk <- apply(df, 1, function(x) !x %in% x[duplicated(x)])
cbind(df, t(chk))
#> Col1 Col2 Col3 1 2 3
#> 1 0 1 -1 TRUE TRUE TRUE
#> 2 1 0 0 TRUE FALSE FALSE
#> 3 1 1 1 FALSE FALSE FALSE
#> 4 0 1 0 FALSE TRUE FALSE
#> 5 1 1 0 FALSE FALSE TRUE
#> 6 -1 0 1 TRUE TRUE TRUE
#> 7 0 -2 1 TRUE TRUE TRUE
我们可以使用 dplyr 和 rowwise()
:
library(dplyr)
df %>% rowwise %>%
mutate(across(starts_with('Col'), ~ sum(c_across(starts_with('Col')) == .x), .names = "{.col}_uni"),
across(ends_with('uni'), ~ifelse(.x==1, str_remove(deparse(substitute(.x)), '_uni$'), NA)))
# A tibble: 7 × 7
# Rowwise:
X Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
<chr> <int> <int> <int> <chr> <chr> <chr>
1 Row1 0 1 -1 Col1 Col2 Col3
2 Row2 1 0 0 Col1 NA NA
3 Row3 1 1 1 NA NA NA
4 Row4 0 1 0 NA Col2 NA
5 Row5 1 1 0 NA NA Col3
6 Row6 -1 0 1 Col1 Col2 Col3
7 Row7 0 -2 1 Col1 Col2 Col3
我还推荐@caldwellst 建议的更简单的“col_names-less”方法,我的回答中的简化代码是:
libarry(dplyr)
df %>% rowwise %>%
mutate(across(starts_with('Col'),
~sum(c_across(starts_with('Col')) == .x) == 1,
.names = "{.col}_uni"))
# A tibble: 7 × 7
# Rowwise:
X Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
<chr> <int> <int> <int> <lgl> <lgl> <lgl>
1 Row1 0 1 -1 TRUE TRUE TRUE
2 Row2 1 0 0 TRUE FALSE FALSE
3 Row3 1 1 1 FALSE FALSE FALSE
4 Row4 0 1 0 FALSE TRUE FALSE
5 Row5 1 1 0 FALSE FALSE TRUE
6 Row6 -1 0 1 TRUE TRUE TRUE
7 Row7 0 -2 1 TRUE TRUE TRUE
A base R 解决方案,按行应用
data.frame( dat, setNames( data.frame( t(apply( dat, 1, function(x){
tf=!duplicated(x, fromLast=F)&!duplicated(x, fromLast=T);
ifelse( tf,colnames(dat)[tf],NA) } ) )), paste0(colnames(dat),"_uni") ) )
Col1 Col2 Col3 Col1_uni Col2_uni Col3_uni
Row1 0 1 -1 Col1 Col2 Col3
Row2 1 0 0 Col1 <NA> <NA>
Row3 1 1 1 <NA> <NA> <NA>
Row4 0 1 0 <NA> Col2 <NA>
Row5 1 1 0 <NA> <NA> Col3
Row6 -1 0 1 Col1 Col2 Col3
Row7 0 -2 1 Col1 Col2 Col3
数据
dat <- structure(list(Col1 = c(0L, 1L, 1L, 0L, 1L, -1L, 0L), Col2 = c(1L,
0L, 1L, 1L, 1L, 0L, -2L), Col3 = c(-1L, 0L, 1L, 0L, 0L, 1L, 1L
)), class = "data.frame", row.names = c("Row1", "Row2", "Row3",
"Row4", "Row5", "Row6", "Row7"))