R 按行选择5个最高值,并输出这些值的列名
我有一个类似的问题,如下所述()。我想按行输出另一个线程中描述的五个最高值。此外,我还需要另外五列,其中列标题的名称为该值。作为下面的一个例子,我在v1列中这样做了(首先是names_)。我已经试了几个小时,但没有成功R 按行选择5个最高值,并输出这些值的列名,r,R,我有一个类似的问题,如下所述()。我想按行输出另一个线程中描述的五个最高值。此外,我还需要另外五列,其中列标题的名称为该值。作为下面的一个例子,我在v1列中这样做了(首先是names_)。我已经试了几个小时,但没有成功 df <- data.frame(v1 = c(0,1,2,3,4,NA), v2 = c(23,6,3,21,4,NA), v3 = c(22,22,24,87,6,NA),
df <- data.frame(v1 = c(0,1,2,3,4,NA),
v2 = c(23,6,3,21,4,NA),
v3 = c(22,22,24,87,6,NA),
v4 = c(2,32,6,58,5,NA),
v5 = c(5,22,65,86,4,NA)
)
df$first <- apply(df, 1, max)
df$second <- apply(df, 1, function(x) -sort(-x[1:5])[2])
df$third <- apply(df, 1, function(x) -sort(-x[1:5])[3])
df$fifth <- apply(df, 1, function(x) -sort(-x[1:5])[4])
df$sixth <- apply(df, 1, function(x) -sort(-x[1:5])[5])
df$sixth <- apply(df, 1, function(x) -sort(-x[1:5])[5])
names_first=c("v2","v4","v5","v3","v3")
df <- cbind(df,names_first)
df您可以在1apply
命令中执行所有这些操作。使用顺序
我们得到每行前5个值的索引。使用该索引,我们可以添加前5个值以及列名
n <- 5
cols <- paste0('col', 1:n)
name_cols <- paste0('name', 1:n)
df[c(cols, name_cols)] <- t(apply(df, 1, function(x) {
inds <- order(x, decreasing = TRUE)[1:n]
c(x[inds], names(df)[inds])
}))
df <- type.convert(df)
df
# v1 v2 v3 v4 v5 col1 col2 col3 col4 col5 name1 name2 name3 name4 name5
#1 0 23 22 2 5 23 22 5 2 0 v2 v3 v5 v4 v1
#2 1 6 22 32 22 32 22 22 6 1 v4 v3 v5 v2 v1
#3 2 3 24 6 65 65 24 6 3 2 v5 v3 v4 v2 v1
#4 3 21 87 58 86 87 86 58 21 3 v3 v5 v4 v2 v1
#5 4 4 6 5 4 6 5 4 4 4 v3 v4 v1 v2 v5
n您可以在1apply
命令中执行所有这些操作。使用顺序
我们得到每行前5个值的索引。使用该索引,我们可以添加前5个值以及列名
n <- 5
cols <- paste0('col', 1:n)
name_cols <- paste0('name', 1:n)
df[c(cols, name_cols)] <- t(apply(df, 1, function(x) {
inds <- order(x, decreasing = TRUE)[1:n]
c(x[inds], names(df)[inds])
}))
df <- type.convert(df)
df
# v1 v2 v3 v4 v5 col1 col2 col3 col4 col5 name1 name2 name3 name4 name5
#1 0 23 22 2 5 23 22 5 2 0 v2 v3 v5 v4 v1
#2 1 6 22 32 22 32 22 22 6 1 v4 v3 v5 v2 v1
#3 2 3 24 6 65 65 24 6 3 2 v5 v3 v4 v2 v1
#4 3 21 87 58 86 87 86 58 21 3 v3 v5 v4 v2 v1
#5 4 4 6 5 4 6 5 4 4 4 v3 v4 v1 v2 v5
n在asplit
之后,您可以在lappy
中排序
,然后简单地cbind
结果:
tt <- lapply(asplit(df, 1), function(x) head(sort(x, TRUE, TRUE), 5))
#tt <- lapply(asplit(df, 1), sort, TRUE, TRUE) #With the given data also this will work
cbind(df, do.call(rbind, tt), do.call(rbind, lapply(tt, names)))
# v1 v2 v3 v4 v5 v2 v3 v5 v4 v1 1 2 3 4 5
#1 0 23 22 2 5 23 22 5 2 0 v2 v3 v5 v4 v1
#2 1 6 22 32 22 32 22 22 6 1 v4 v3 v5 v2 v1
#3 2 3 24 6 65 65 24 6 3 2 v5 v3 v4 v2 v1
#4 3 21 87 58 86 87 86 58 21 3 v3 v5 v4 v2 v1
#5 4 4 6 5 4 6 5 4 4 4 v3 v4 v1 v2 v5
#6 NA NA NA NA NA NA NA NA NA NA v1 v2 v3 v4 v5
tt在asplit
之后,您可以在lappy
中排序
,然后简单地cbind
结果:
tt <- lapply(asplit(df, 1), function(x) head(sort(x, TRUE, TRUE), 5))
#tt <- lapply(asplit(df, 1), sort, TRUE, TRUE) #With the given data also this will work
cbind(df, do.call(rbind, tt), do.call(rbind, lapply(tt, names)))
# v1 v2 v3 v4 v5 v2 v3 v5 v4 v1 1 2 3 4 5
#1 0 23 22 2 5 23 22 5 2 0 v2 v3 v5 v4 v1
#2 1 6 22 32 22 32 22 22 6 1 v4 v3 v5 v2 v1
#3 2 3 24 6 65 65 24 6 3 2 v5 v3 v4 v2 v1
#4 3 21 87 58 86 87 86 58 21 3 v3 v5 v4 v2 v1
#5 4 4 6 5 4 6 5 4 4 4 v3 v4 v1 v2 v5
#6 NA NA NA NA NA NA NA NA NA NA v1 v2 v3 v4 v5
tt你能发布你想要的输出是什么样子吗?你能发布你想要的输出是什么样子吗?嗯,我刚刚意识到我也有NA值,甚至是整行的NAs值。有什么办法可以解决这个问题吗?@titeuf你能提供一个额外的数据集来显示这些情况吗?我已经为所有NAs添加了一个新行,现在它不再工作了。我可以手动将其设置为“999”,最后将其更改为NA,但这意味着它仍在为名称列选择值(名称第一、名称第二等)。我也在考虑如果第四和第五等级的值相同,就选择值。但是需要考虑的是,我在部门里做了更多的工作。我已经为这个案例更新了它-只需要为NA
设置sort
。嗯,我刚刚意识到我也有NA值,甚至整行都有NA值。有什么办法可以解决这个问题吗?@titeuf你能提供一个额外的数据集来显示这些情况吗?我已经为所有NAs添加了一个新行,现在它不再工作了。我可以手动将其设置为“999”,最后将其更改为NA,但这意味着它仍在为名称列选择值(名称第一、名称第二等)。我也在考虑如果第四和第五等级的值相同,就选择值。但需要考虑的是,我在部门里做了更多的工作。我已经为这个案例更新了它-只需要设置排序
,也可以设置NA
。