我有一个称为test的数据框。我想对数据框进行排序,并在左列(sstart
)中移动较小的值,并在右列(send
)中保留较大的值。我可以通过使用if else条件并创建两个带有排序值的新列来实现。我们如何在R中更有效地做到这一点?
test<- structure(list(sstart = c(425L, 387L, 436L, 219L,
232L), send = c(125L, 487L, 136L, 3191L, 132L
)), .Names = c("sstart", "send"), row.names = c(4L, 14L, 17L,
23L, 27L), class = "data.frame")
我想要的结果:
sstart send
125 425
387 487
136 436
219 3191
132 232
答案 0 :(得分:3)
已修订
对不起,在重读您的问题后,我发现我误会了您:您只想在每行中对前两列进行排序。那不是我原来的代码(下面保留)所做的。您想要的是什么
data.frame(t(apply(test[,1:2],1,sort))) %>%
rename(sstart=X1, send=X2) %>% dplyr::bind_cols(test[,-1:-2])
我在测试的前两列使用逐行应用(那里是“ 1”),所应用的功能是排序。这为我们提供了一个横向矩阵,因此我t
对其进行了摆放并将其转换为data.frame,然后将其绑定回原始test
的其余部分。结果:
sstart send
1 125 425
2 387 487
3 136 436
4 219 3191
5 132 232
很抱歉混淆。
错误代码:
matrix(sort(unlist(test)),ncol=2) %>% data.frame() %>% dplyr::rename(sstart=X1,send=X2)
不公开测试将其转换为向量,我们将其排序并放入具有两列的矩阵中。矩阵默认为按列填充,因此较小的列将进入第一列,较大的列将进入第二列。我们将此矩阵移到data.frame中,并将列sstart和send重命名。瞧!
sstart send
1 125 387
2 132 425
3 136 436
4 219 487
5 232 3191
如果测试中还有其他列需要保留:
matrix(sort(unlist(test[,1:2])),ncol=2) %>% data.frame() %>%
dplyr::rename(sstart=X1,send=X2) %>%
dplyr::bind_cols(test[,-1:-2])
答案 1 :(得分:2)
您可以使用pmax
和pmin
,但是如果不临时存储至少一个值就无法交换两个值:
# temp vectors of the columns to "swap" the values as required
low <- pmin(test$sstart, test$send)
high <- pmax(test$sstart, test$send)
# exchange the columns
test$sstart <- low
test$send <- high
# result
test
# sstart send
# 4 125 425
# 14 387 487
# 17 136 436
# 23 219 3191
# 27 132 232
警告:如果您的数据中出现NA
,则可能会丢失信息。您可以将NA
设置为适当的默认值来解决:
E。 G。如果您添加包含NA
值的另一行
test[6,]$sstart <- NA
test[6,]$send <- 100
您将获得两个NA
,而不是一个+第二个值:
sstart send
4 125 425
14 387 487
17 136 436
23 219 3191
27 132 232
NA NA NA
答案 2 :(得分:0)
我会这样:
split(test,row(test)) %>%
purrr::map_dfr(~{
sort(.x) %>%
setNames(c("sstart","send"))
})