【发布时间】:2021-12-05 03:01:52
【问题描述】:
我有兴趣在一系列列中进行字符串检测和值比较。如果在列中找到字符串(在本例中为ZSD),则需要比较它们在另一列中的对应值。
输入
我的输入如下:
a.zsd a.test b.zsd b.test c.zsd c.test d.zsd d.test
'ZSD' 0.0 'ZAD' 1.0 NA 0.5 'ZAD' 1.0
'ZAD' 1.0 NA 0.0 NA 0.5 'ZSD' 0.0
NA 0.5 NA 0.5 'ZAD' 0.5 NA 0.5
'Not Achieved ZSD' 0.0 NA 0.5 'ZAD' 0.5 NA 0.5
'ZSD' 1.0 'ZSD' 0.5 NA 0.5 'ZSD' 0.0
NA 0.0 NA 0.0 NA 0.5 NA 0.0
NA 1.0 'ZSD' 0.0 'ZSD' 0.5 'ZSD' 1.0
输出
在我的输出中,我想要两个额外的列 smallest.test 和 zsd.level:
a.zsd a.test b.zsd b.test c.zsd c.test d.zsd d.test smallest.test zsd.level
'ZSD' 0.0 'ZAD' 1.0 NA 0.5 'ZAD' 1.0 0.0 a
'ZAD' 1.0 NA 0.0 NA 0.5 'ZSD' 0.0 0.0 d
NA 0.5 NA 0.5 'ZAD' 0.5 NA 0.5 0.0 NA
'Not Achieved ZSD' 0.0 NA 0.5 'ZAD' 0.5 NA 0.5 0.0 a
'ZSD' 1.0 'ZSD' 0.5 NA 0.5 'ZSD' 0.0 0.0 d
NA 0.0 NA 0.0 NA 0.5 NA 0.0 0.0 NA
NA 1.0 'ZSD' 0.0 'ZSD' 0.5 'ZSD' 1.0 0.0 b
信息:
我的数据框有一百多列。我只对名称以字符串.zsd 结尾的某些列感兴趣。这些列可以具有NA 或以下字符串值之一ZAD、ZSD、Not Achieved ZSD。具有.zsd 字符串名称的每一列都有一个关联的.test 列。
要求
我想要在输出 smallest.test 和 zsd.level 中添加两个新列。要求如下:
-
遍历以字符串
.zsd结尾的列名 -
在这些列中检测字符串
ZSD -
如果
ZSD字符串仅在其中一列中找到,则在输出列zsd.level中返回该列的名称,并从以.test结尾的列名称返回相应的值以返回到输出列smallest.test。 -
如果没有一列包含字符串
ZSD,则在输出列zsd.level中返回NA,并在对应的输出列smallest.test中返回0.0。 -
如果多列包含字符串
ZSD,则选择对应.test列中值最小的列并在输出中返回。 -
如果多个列包含字符串
ZSD,并且它们都具有对应.test列的相同值,则选择输出的最后一列名称和.test的对应值作为输出。
输入()
dput(df)
structure(list(a.zsd = c("ZSD", "ZAD", NA, "Not Achieved ZSD", "ZSD", NA, NA),
a.test = c(0, 1, 0.5, 0, 1, 0, 1),
b.zsd = c("ZAD", NA, NA, NA, "ZSD", NA, "ZSD"),
b.test = c(1, 0, 0.5, 0.5, 0.5, 0, 0),
c.zsd = c(NA, NA, "ZAD", "ZAD", NA, NA, "ZSD"),
c.test = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5),
d.zsd = c("ZAD", "ZSD", NA, NA, "ZSD", NA, "ZSD"),
d.test = c(1, 0, 0.5, 0.5, 0, 0, 1)),
class = "data.frame", row.names = c(NA, -7L))
部分解决方案
基于以下帖子:String matching over multiple columns with specific string names,此代码可以迭代并选择 .zsd 列并返回输出中最高的列名。但它没有考虑.test字段的对应值。对此的任何帮助将不胜感激。
library(dplyr)
library(tidyr)
library(stringr)
df %>%
mutate(across(contains("zsd"), ~case_when(str_detect(., "ZSD") ~ cur_column()), .names = 'new_{col}')) %>%
unite(zsd_level, starts_with('new'), na.rm = TRUE, sep = ' ') %>%
mutate(zsd_level = str_remove_all(zsd_level, ".zsd"),
zsd_level = str_sub(zsd_level, -1))
【问题讨论】:
标签: r string comparison multiple-columns