【问题标题】:Swapping the values in columns with the condition of another column in R将列中的值与 R 中另一列的条件交换
【发布时间】:2019-11-04 20:30:59
【问题描述】:

对于下面的数据,如果p.2的值大于0.5,我想交换column-1(b.1.1)和column-2b.1.2的值, column-3(b.2.1) and column-4 b.2.2 , column-5(b.3.1) and column-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 对的行值。 任何帮助表示赞赏。

【问题讨论】:

  • 第三行,应该是 ` 0.42685669 -0.06088828 0.8330836 -1.0643744 0.6661079 0.1184059 ` 如果你注意到,第一对列值被交换,第二对值被交换,第三对由于 p.2 大于 0.5,因此交换了一对值

标签: r dataframe multiple-columns swap


【解决方案1】:

另一个只使用 base 而没有正则表达式的选项是

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)

这可能比上一个答案慢很多,但对于小数据集可能更容易修改

【讨论】:

    【解决方案2】:

    这是一个选项。创建一个索引以子集以“b”开头的列(“i1”),并创建另一个索引以子集行(“i2”)。然后,split 将数据集转换为基于列名相似度的数据集的list 子集化行('i2'),循环遍历listreverse 元素、cbind@ 987654326@ 的 data.frames 并将其更新为原始数据集行/列

    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
    

    另一个选项是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
    

    数据

    mydata <- structure(list(b.1.1 = c(0.40772028, -0.77459375, -0.06088828, 
    1.54204242, -0.7339731), b.1.2 = c(0.43064446, 0.79860856, 0.42685669, 
    -0.08987067, 1.34927693), b.2.1 = c(0.2697412, -0.5263932, -1.0643744, 
    -0.7365012, 0.2202689), b.2.2 = c(0.9191535, -0.5640303, 0.8330836, 
    0.3762336, 0.2422944), b.3.1 = c(0.1523922, 0.5131236, 0.1184059, 
    0.3781115, 1.5267535), b.3.2 = c(0.7629324, 0.6472614, 0.6661079, 
    -0.734034, -0.5207967), p.1 = c(0.86061981, 0.63494425, 0.07382585, 
    0.65481949, 0.54425551), p.2 = c(0.1393802, 0.3650557, 0.9261742, 
    0.3451805, 0.4557445)), class = "data.frame", row.names = c("1", 
    "2", "3", "4", "5"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      • 2022-07-27
      • 1970-01-01
      • 2021-07-02
      • 2021-10-01
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多