将列中的值与R中另一列的条件交换

问题描述 投票:0回答:2

对于以下数据,如果p.2值大于0.5,我想交换列1 (b.1.1)和列2 b.1.2的值,第3列(b.2.1)和第4列b.2.2,第5列(b.3.1)和第6列b.3.2

 mydata
            b.1.1       b.1.2      b.2.1      b.2.2     b.3.1      b.3.2        p.1       p.2
    1  0.40772028  0.43064446  0.2697412  0.9191535 0.1523922  0.7629324 0.86061981 0.1393802
    2 -0.77459375  0.79860856 -0.5263932 -0.5640303 0.5131236  0.6472614 0.63494425 0.3650557
    3 -0.06088828  0.42685669 -1.0643744  0.8330836 0.1184059  0.6661079 0.07382585 0.9261742
    4  1.54204242 -0.08987067 -0.7365012  0.3762336 0.3781115 -0.7340340 0.65481949 0.3451805
    5 -0.73397310  1.34927693  0.2202689  0.2422944 1.5267535 -0.5207967 0.54425551 0.4557445

例如,在第一行中,在p.1p.2之间,p.2不大于0.5,我没有交换此行的任何值。在第三行中,p.2大于0.5,因此,我想交换上面编写的每个beta对的行值。任何帮助表示赞赏。

r dataframe multiple-columns swap
2个回答
1
投票

仅使用基数而不使用正则表达式的另一种选择是

reorderRows <- function(x, nullFrame){
  for(i in length(x)){
    if(x[i, 8] > 0.5)x = x[c(2,1,4,3,6,5,7,8)]
    nullFrame <- rbind(nullFrame, x)
  }
  return(nullFrame)
}

应用:

dat <- data.frame(matrix(rnorm(80), ncol = 8))
colnames(dat) <- c("b.1.1", "b.1.2", "b.2.1", "b.2.2", 
                   "b.3.1", "b.3.2", "p.1", "p.2")

emptyFrame <- NULL
dat2 <- reorderRows(dat, emptyFrame)

它可能比以前的答案要慢很多,但是对于较小的数据集,更容易修改


1
投票

这里是一个选项。创建索引以子集以'b'('i1')开头的列,并创建另一个索引子集以行('i2')。然后,在对行进行子集('i2')之后,根据列名的相似性将split数据集转换为list数据集,循环遍历listrev设置元素,cbind将[ C.]并将其更新为原始数据集的行/列

list

另一种选择是i1 <- startsWith(names(mydata), "b") i2 <- mydata$p.2 > 0.5 mydata[i2, i1] <- do.call(cbind, lapply(split.default(mydata[i2, i1, drop = FALSE], sub("\\.\\d+$", "", names(mydata)[i1])), rev)) mydata # b.1.1 b.1.2 b.2.1 b.2.2 b.3.1 b.3.2 p.1 p.2 #1 0.4077203 0.43064446 0.2697412 0.9191535 0.1523922 0.7629324 0.86061981 0.1393802 #2 -0.7745937 0.79860856 -0.5263932 -0.5640303 0.5131236 0.6472614 0.63494425 0.3650557 #3 0.4268567 -0.06088828 0.8330836 -1.0643744 0.6661079 0.1184059 0.07382585 0.9261742 #4 1.5420424 -0.08987067 -0.7365012 0.3762336 0.3781115 -0.7340340 0.65481949 0.3451805 #5 -0.7339731 1.34927693 0.2202689 0.2422944 1.5267535 -0.5207967 0.54425551 0.4557445 ,我们将其转换为'long'格式,以该形式进行转换,然后重塑为'wide'格式

tidyverse

数据

library(dplyr)
library(tidyr)
library(stringr)
library(tibble)
mydata %>% 
   rownames_to_column('rn') %>%
   pivot_longer(cols = -c(rn, p.1, p.2)) %>%
   group_by(rn, grp = str_remove(name, "\\.\\d+$")) %>% 
   mutate(value = case_when(p.2 > 0.5 ~ rev(value), TRUE ~ value)) %>% 
   ungroup %>% 
   select(-grp) %>% 
   pivot_wider(names_from = name, values_from = value) %>%
   select(names(mydata)) 
# A tibble: 5 x 8
#   b.1.1   b.1.2  b.2.1  b.2.2 b.3.1  b.3.2    p.1   p.2
#   <dbl>   <dbl>  <dbl>  <dbl> <dbl>  <dbl>  <dbl> <dbl>
#1  0.408  0.431   0.270  0.919 0.152  0.763 0.861  0.139
#2 -0.775  0.799  -0.526 -0.564 0.513  0.647 0.635  0.365
#3  0.427 -0.0609  0.833 -1.06  0.666  0.118 0.0738 0.926
#4  1.54  -0.0899 -0.737  0.376 0.378 -0.734 0.655  0.345
#5 -0.734  1.35    0.220  0.242 1.53  -0.521 0.544  0.456
© www.soinside.com 2019 - 2024. All rights reserved.