R移动某个值,同时保持字符数据帧的顺序
Posted
技术标签:
【中文标题】R移动某个值,同时保持字符数据帧的顺序【英文标题】:R move certain value while remain order from a dataframe of characters 【发布时间】:2021-05-12 03:19:20 【问题描述】:我尝试在保留订单的同时从当前数据框移动,但它不能按我的意愿工作。尝试使用 grep 捕获 rest1、rest2 作品,但是当我尝试重新排序它们时,它会给出带有所有字符的向量:(
原来的 DF 看起来像:
ID | rank1 | rank2 | rank3 | rank4 | ... |
---|---|---|---|---|---|
1 | apple | rest1 | orange | grape | ... |
2 | rest2 | orange | rest1 | apple | ... |
所以预期的表格应该看起来像,对于每一行,“rest1”|“rest2”应该移到最后,df应该看起来像:
ID | rank1 | rank2 | rank3 | rank4 | ... |
---|---|---|---|---|---|
1 | apple | orange | grape | ... | rest1 |
2 | orange | apple | ... | rest1 | rest2 |
我将所有 rest1 和 rest2 替换为 NA 值,然后移至最后一列。但是下面的代码不起作用。
df % relocate(where(is.na), .after = last_col())
【问题讨论】:
relocate
用于更改列位置,一次整列;它不会更改每列中的单个元素。
【参考方案1】:
这是一种方法,
setNames(as.data.frame(
t(apply(as.matrix(dat), 1,
function(row) c(grep("^rest", row, value = TRUE, invert = TRUE),
grep("^rest", row, value = TRUE))))),
names(dat))
# ID rank1 rank2 rank3 rank4 rank9
# 1 1 apple orange grape <NA> rest1
# 2 2 orange apple <NA> rest2 rest1
另一种方式,简单一点:
setNames(as.data.frame(
t(apply(as.matrix(dat), 1, function(row) row[order(grepl("^rest", row))]))),
names(dat))
这应该保持组内的自然顺序(例如,第一组是那些不包含"^rest"
的组)。
如果您需要它们,您可以添加sort(.)
,而不是按照每行显示的顺序。
注意:我从列名rank#
推断列本身具有相关性,在这种情况下,此操作会使您的数据排序错误。如果您必须这样做,因为它在某一时刻被正确排序并且现在在框架中格式不正确,我建议您考虑修复导入过程,而不是依赖事后修复它。
数据
dat <- structure(list(ID = 1:2, rank1 = c("apple", "rest2"), rank2 = c("rest1", "orange"), rank3 = c("orange", "rest1"), rank4 = c("grape", "apple"), rank9 = c(NA, NA)), class = "data.frame", row.names = c("1", "2"))
【讨论】:
谢谢!我不确定 function(row) 是如何工作的,它是否像 "rest^" 和非 "rest^" 值的列组合一样工作?所以默认情况下 grep 返回 (invert = False) ?row
是一个character
向量。第一个grep
返回所有不以"rest"
开头的字符串的值,这包括NA
s(在末尾)。第二个grep
返回所有以"rest"
开头的字符串的值。通过c(.)
将它们连接在一起,我们现在应该可以确保新向量的长度与length(row)
相同,并且其元素已重新排序。
看看我的替代方法,有点简单。以上是关于R移动某个值,同时保持字符数据帧的顺序的主要内容,如果未能解决你的问题,请参考以下文章