用 R 中的用户定义函数替换 Dataframe 列值
Replace Dataframe Column Values with User Defined Function in R
我在一个列中有一组值,我正试图用一个 since 值替换
col1
a
a;a;b;c
c;b;a
NA
b;b;b
我想用 mixed
或单个现值替换所有值,例如 a;a;a;a
变为 a
预期输出
col1
a
Mixed
Mixed
NA
b
代码
grouping = function(x){
y = as.list(strsplit(x, ";")[[1]])
#select first element, and test if each is the same element.
z = ""
for (i in 1:length(y)){
if (as.character(y[1]) != as.character(y[i])) {
z = 'mixed'
break
} else {
z = as.character(y[1])
}
}
return(z)
}
db %>%
select(col1) %>%
mutate(
test = grouping(col1)
)
我已经尝试了几种不同的方法,要么以它根本无法工作而告终,要么为所有内容提供 a
的值
我们可以从'col1'中提取字母的子串,用[=17=检查不同元素的个数],用case_when
把那些有多个唯一元素的改成'Mixed'
library(dplyr)
library(stringr)
library(purrr)
df1 %>%
mutate(col1 = case_when(map_dbl(str_extract_all(col1,
"[a-z]"), n_distinct) >1 ~ "Mixed",
is.na(col) ~ NA_character_,
TRUE ~ substr(col1, 1, 1)))
-输出
# col1
#1 a
#2 Mixed
#3 Mixed
#4 <NA>
#5 b
或者另一种选择是用 separate_rows
分隔符拆分列,并按 row_number
到 summarise
具有多行的元素进行分组(在 distinct
) 为 'Mixed'
library(tidyr)
df1 %>%
mutate(rn = row_number()) %>%
separate_rows(col1) %>%
distinct() %>%
group_by(rn) %>%
summarise(col1 = case_when(n() > 1 ~ 'Mixed', TRUE ~ first(col1)),
.groups = 'drop') %>%
select(-rn)
-输出
# A tibble: 5 x 1
# col1
# <chr>
#1 a
#2 Mixed
#3 Mixed
#4 <NA>
#5 b
或使用 base R
和紧凑选项
v1 <- gsub("([a-z])\1+", "\1", gsub(";", "", df1$col1))
replace(v1, nchar(v1) > 1, "Mixed")
#[1] "a" "Mixed" "Mixed" NA "b"
OP 函数中的问题是它仅提取第一个 [[1]]
list
元素
as.list(strsplit(x, ";")[[1]])
as strsplit
returns a list
其中 length
等于初始数据的行数。所以,基本上只选择第一个,它被回收
数据
df1 <- structure(list(col1 = c("a", "a;a;b;c", "c;b;a", NA, "b;b;b")),
class = "data.frame", row.names = c(NA,
-5L))
您也可以考虑将此用于您的功能并使用 base R
:
#Function
myfun <- function(x)
{
y <- unlist(strsplit(x, ";"))
if(length(unique(y))==1)
{
z <- unique(y)
} else
{
z <- 'Mixed'
}
}
#Apply
df$New <- apply(df,1,myfun)
输出:
df
col1 New
1 a a
2 a;a;b;c Mixed
3 c;b;a Mixed
4 <NA> <NA>
5 b;b;b b
使用了一些数据:
#Data
df <- structure(list(col1 = c("a", "a;a;b;c", "c;b;a", NA, "b;b;b")), class = "data.frame", row.names = c(NA,
-5L))
通过定义用户函数的基本 R 选项f
f <- function(x) ifelse(length(u <- unique(unlist((strsplit(x, ";"))))) > 1, "Mixed", u)
这样
> transform(df, col1 = Vectorize(f)(col1))
col1
1 a
2 Mixed
3 Mixed
4 <NA>
5 b
您可以将 grouping
函数编写为:
grouping <- function(x) {
sapply(strsplit(x, ';'), function(x)
if(length(unique(x)) == 1) unique(x) else 'Mixed')
}
db$test <- grouping(db$col1)
db
# col1 test
#1 a a
#2 a;a;b;c Mixed
#3 c;b;a Mixed
#4 <NA> <NA>
#5 b;b;b b
我在一个列中有一组值,我正试图用一个 since 值替换
col1
a
a;a;b;c
c;b;a
NA
b;b;b
我想用 mixed
或单个现值替换所有值,例如 a;a;a;a
变为 a
预期输出
col1
a
Mixed
Mixed
NA
b
代码
grouping = function(x){
y = as.list(strsplit(x, ";")[[1]])
#select first element, and test if each is the same element.
z = ""
for (i in 1:length(y)){
if (as.character(y[1]) != as.character(y[i])) {
z = 'mixed'
break
} else {
z = as.character(y[1])
}
}
return(z)
}
db %>%
select(col1) %>%
mutate(
test = grouping(col1)
)
我已经尝试了几种不同的方法,要么以它根本无法工作而告终,要么为所有内容提供 a
的值
我们可以从'col1'中提取字母的子串,用[=17=检查不同元素的个数],用case_when
把那些有多个唯一元素的改成'Mixed'
library(dplyr)
library(stringr)
library(purrr)
df1 %>%
mutate(col1 = case_when(map_dbl(str_extract_all(col1,
"[a-z]"), n_distinct) >1 ~ "Mixed",
is.na(col) ~ NA_character_,
TRUE ~ substr(col1, 1, 1)))
-输出
# col1
#1 a
#2 Mixed
#3 Mixed
#4 <NA>
#5 b
或者另一种选择是用 separate_rows
分隔符拆分列,并按 row_number
到 summarise
具有多行的元素进行分组(在 distinct
) 为 'Mixed'
library(tidyr)
df1 %>%
mutate(rn = row_number()) %>%
separate_rows(col1) %>%
distinct() %>%
group_by(rn) %>%
summarise(col1 = case_when(n() > 1 ~ 'Mixed', TRUE ~ first(col1)),
.groups = 'drop') %>%
select(-rn)
-输出
# A tibble: 5 x 1
# col1
# <chr>
#1 a
#2 Mixed
#3 Mixed
#4 <NA>
#5 b
或使用 base R
和紧凑选项
v1 <- gsub("([a-z])\1+", "\1", gsub(";", "", df1$col1))
replace(v1, nchar(v1) > 1, "Mixed")
#[1] "a" "Mixed" "Mixed" NA "b"
OP 函数中的问题是它仅提取第一个 [[1]]
list
元素
as.list(strsplit(x, ";")[[1]])
as strsplit
returns a list
其中 length
等于初始数据的行数。所以,基本上只选择第一个,它被回收
数据
df1 <- structure(list(col1 = c("a", "a;a;b;c", "c;b;a", NA, "b;b;b")),
class = "data.frame", row.names = c(NA,
-5L))
您也可以考虑将此用于您的功能并使用 base R
:
#Function
myfun <- function(x)
{
y <- unlist(strsplit(x, ";"))
if(length(unique(y))==1)
{
z <- unique(y)
} else
{
z <- 'Mixed'
}
}
#Apply
df$New <- apply(df,1,myfun)
输出:
df
col1 New
1 a a
2 a;a;b;c Mixed
3 c;b;a Mixed
4 <NA> <NA>
5 b;b;b b
使用了一些数据:
#Data
df <- structure(list(col1 = c("a", "a;a;b;c", "c;b;a", NA, "b;b;b")), class = "data.frame", row.names = c(NA,
-5L))
通过定义用户函数的基本 R 选项f
f <- function(x) ifelse(length(u <- unique(unlist((strsplit(x, ";"))))) > 1, "Mixed", u)
这样
> transform(df, col1 = Vectorize(f)(col1))
col1
1 a
2 Mixed
3 Mixed
4 <NA>
5 b
您可以将 grouping
函数编写为:
grouping <- function(x) {
sapply(strsplit(x, ';'), function(x)
if(length(unique(x)) == 1) unique(x) else 'Mixed')
}
db$test <- grouping(db$col1)
db
# col1 test
#1 a a
#2 a;a;b;c Mixed
#3 c;b;a Mixed
#4 <NA> <NA>
#5 b;b;b b