R 获取字符串中的最小数字
我有一个数据框,由捕获不同事件的列组成。受访者填写他们经历这些事件的年龄。对于他们经历过多次的任何给定事件,他们用分号分隔经历的年龄(例如,如果他们在5、6、7岁时经历过,他们将在该特定列中输入5;6;7)。对于他们没有经历过的事件,受访者将其留空 由于有20多列,我将所有列连接到一个单独的列中,从而生成一个字符列。我想提取该字符串中的最小数字。我无法强制将列转换为数字数据类型,因为某些事件会被应答者经历多次,并被R解释为字符串(例如“5;6;7”) 我的数据如下所示:R 获取字符串中的最小数字,r,string,R,String,我有一个数据框,由捕获不同事件的列组成。受访者填写他们经历这些事件的年龄。对于他们经历过多次的任何给定事件,他们用分号分隔经历的年龄(例如,如果他们在5、6、7岁时经历过,他们将在该特定列中输入5;6;7)。对于他们没有经历过的事件,受访者将其留空 由于有20多列,我将所有列连接到一个单独的列中,从而生成一个字符列。我想提取该字符串中的最小数字。我无法强制将列转换为数字数据类型,因为某些事件会被应答者经历多次,并被R解释为字符串(例如“5;6;7”) 我的数据如下所示: df <- dat
df <- data.frame(ID = c("001", "002", "003", "004"),
concatenated = c("NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA",
"3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA",
"NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA",
"NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9"))
df$concatenated <- as.character(df$concatenated)
ID concatenated smallest_number
1 001 NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA 4
2 002 3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA 3
3 003 NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA 2
4 004 NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9 4
谢谢!非常感谢 假设您的数据结构如下:
DF <- data.frame(ID = 1:4,
age = c("5", "5;6;7", "20;15;12", "2;4"),
stringsAsFactors = FALSE)
如果数字有时不出现,只需排除这些行即可
i <- grep("[0-9]", DF$age) # rows with numbers somewhere
DF$min_age <- NA_character_
DF$min_age[i] <- vapply(strsplit(DF$age[i], split = "[^0-9]"),
function(x) min(as.numeric(x), na.rm = TRUE),
double(1))
i假设您的数据结构如下:
DF <- data.frame(ID = 1:4,
age = c("5", "5;6;7", "20;15;12", "2;4"),
stringsAsFactors = FALSE)
如果数字有时不出现,只需排除这些行即可
i <- grep("[0-9]", DF$age) # rows with numbers somewhere
DF$min_age <- NA_character_
DF$min_age[i] <- vapply(strsplit(DF$age[i], split = "[^0-9]"),
function(x) min(as.numeric(x), na.rm = TRUE),
double(1))
i我们可以使用gsub
修改元素,使每个项目都有一个下划线分隔的字符串,然后对它们使用scan
和min
df$smallest_number <- sapply(df$concatenated, function(x){
min(scan(text=gsub("; ","_",x), what = numeric(), sep="_"),na.rm=TRUE)})
df
# ID concatenated smallest_number
# 1 001 NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA 4
# 2 002 3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA 3
# 3 003 NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA 2
# 4 004 NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9 4
df$minimable_number我们可以使用gsub
修改元素,使每个项目都有一个下划线分隔的字符串,然后对它们使用scan
和min
df$smallest_number <- sapply(df$concatenated, function(x){
min(scan(text=gsub("; ","_",x), what = numeric(), sep="_"),na.rm=TRUE)})
df
# ID concatenated smallest_number
# 1 001 NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA 4
# 2 002 3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA 3
# 3 003 NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA 2
# 4 004 NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9 4
df$最小_数使用tidyverse
和splitstackshape
可以执行以下操作:
df %>%
mutate(temp = gsub(";", "_", concatenated),
temp = gsub(" ", "", temp)) %>%
cSplit("temp", sep = "_") %>%
gather(var, val, -c(concatenated, ID)) %>%
group_by(ID) %>%
mutate(res = min(val, na.rm = TRUE)) %>%
spread(var, val) %>%
select(ID, concatenated, res)
ID concatenated res
<fct> <chr> <dbl>
1 001 NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA 4.
2 002 3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA 3.
3 003 NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA 2.
4 004 NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9 4.
使用tidyverse
和splitstackshape
可以执行以下操作:
df %>%
mutate(temp = gsub(";", "_", concatenated),
temp = gsub(" ", "", temp)) %>%
cSplit("temp", sep = "_") %>%
gather(var, val, -c(concatenated, ID)) %>%
group_by(ID) %>%
mutate(res = min(val, na.rm = TRUE)) %>%
spread(var, val) %>%
select(ID, concatenated, res)
ID concatenated res
<fct> <chr> <dbl>
1 001 NA_NA_NA_NA_5; 6_NA_4_NA_NA_NA 4.
2 002 3_3_NA_NA_NA_3; 4; 5; 6_NA_NA_NA_NA 3.
3 003 NA_5_4_2_NA_NA_NA_NA_6; 7; 8; 9; 10_NA 2.
4 004 NA_NA_11_12_11_NA_4; 5; 6_NA_NA_9 4.
库(stringr)
df$最小\u编号库(stringr)
df$最小_编号上述仅适用于一个“年龄”列。我需要找到所有列中的最小年龄,有些列有多个年龄响应,用分号分隔,而大多数列为空。您想知道如何从连接的列或单个原始列中提取年龄吗?有关连接版本,请参见我的编辑。谢谢。成功了。但是有很多警告消息:在min中(as.numeric(x),na.rm=TRUE):min没有不丢失的参数;返回Inf。这是否值得关注?谢谢这表明该行中没有数字。在这种情况下,“最小年龄”将是正无穷大,这可能不是你想要的。有没有办法将正无穷大改为NA?非常感谢你的帮助!以上仅适用于一个“年龄”列。我需要找到所有列中的最小年龄,有些列有多个年龄响应,用分号分隔,而大多数列为空。您想知道如何从连接的列或单个原始列中提取年龄吗?有关连接版本,请参见我的编辑。谢谢。成功了。但是有很多警告消息:在min中(as.numeric(x),na.rm=TRUE):min没有不丢失的参数;返回Inf。这是否值得关注?谢谢这表明该行中没有数字。在这种情况下,“最小年龄”将是正无穷大,这可能不是你想要的。有没有办法将正无穷大改为NA?非常感谢你的帮助!在将所有列粘贴到字符串之前更容易找到最小值在将所有列粘贴到字符串之前更容易找到最小值