【问题标题】:Loop through columns in data.frame and make a new data.frame based on calculation in loop循环遍历 data.frame 中的列,并根据循环计算创建一个新的 data.frame
【发布时间】:2015-02-05 14:03:29
【问题描述】:

我有一个大的 data.frame,我想将列中的值连接在一起,然后用输出创建一个新的 data.frame。由于我的 data.frame 有近 1700 列,我认为最简单的方法是遍历这些列。以下是我想做的一个例子。

起始值:

variable1 = c(var1, var2, var3)
variable2 = c(var4, var5, var6)
variable3 = c(var7, var8, var9)
df = data.frame(variable1, variable2, variable3)

预期输出:

  variable1 variable2 variable3
1 var1_var2  var4_var5  var7_var8
2 var1_var3  var4_var6  var7_var9
3 var2_var3  var5_var6  var8_var9

我现在使用的代码是:

index = 1
column = 1

Complexes <- dim(df)[2]
proteins <- dim(df)[1]


complex <-list()
interactions <- list()
complexcol <- list()

for(i in 1:Complexes){
  complex[[column]]=(for(j in 1:proteins){
    for(k in j+1:proteins){
      interactions[index] = c(paste0(corum[i,j],"_",corum[i,k]))
      index = index +1
    }
  })
  column = column + 1
  print(column)
  index = 1
}

当我执行时,它会遍历列,但不会在新列表或 data.frame 中生成输出。

谢谢!

【问题讨论】:

    标签: r loops dataframe


    【解决方案1】:

    您可以使用combn 函数获取所有组合,使此操作成为 1-liner:

    # Build example data
    (dat = data.frame(1:3, 4:6, 7:9))
    #   X1.3 X4.6 X7.9
    # 1    1    4    7
    # 2    2    5    8
    # 3    3    6    9
    
    # Get all combinations of rows
    t(apply(combn(nrow(dat), 2), 2, function(x) paste0(dat[x[1],], "_", dat[x[2],])))
    #      [,1]  [,2]  [,3] 
    # [1,] "1_2" "4_5" "7_8"
    # [2,] "1_3" "4_6" "7_9"
    # [3,] "2_3" "5_6" "8_9"
    

    如果您有一个存储因子的数据框并且想要组合它们的级别,您可以将数据框转换为实际存储字符串的数据框,然后使用相同的代码

    # Make data frame with factors
    (dat = data.frame(X=c("a", "b", "c"), Y=c("d", "e", "f"), Z=c("g", "h", "i")))
    #   X Y Z
    # 1 a d g
    # 2 b e h
    # 3 c f i
    str(dat)
    # 'data.frame': 3 obs. of  3 variables:
    #  $ X: Factor w/ 3 levels "a","b","c": 1 2 3
    #  $ Y: Factor w/ 3 levels "d","e","f": 1 2 3
    #  $ Z: Factor w/ 3 levels "g","h","i": 1 2 3
    
    # Convert to data frame with strings and then use same code
    dat2 <- data.frame(lapply(dat, as.character), stringsAsFactors=F)
    t(apply(combn(nrow(dat2), 2), 2, function(x) paste0(dat2[x[1],], "_", dat2[x[2],])))
    #      [,1]  [,2]  [,3] 
    # [1,] "a_b" "d_e" "g_h"
    # [2,] "a_c" "d_f" "g_i"
    # [3,] "b_c" "e_f" "h_i"
    

    【讨论】:

    • 如果 data.frame 中的值是文本而不是数字,有没有办法将它们保留并连接在一起而不是数字。如果我将此应用于我的实际数据,它只会报告连接在一起的地址。谢谢
    • @JohnLapek 听起来您实际上有一个带有因子而不是文本的数据框——请参阅更新后的问题以了解如何处理这种情况。通常我使用stringsAsFactors=F 创建数据框,以避免在数据争吵期间处理因素。
    【解决方案2】:

    我想在这里使用dplyr 和data.table 做出更多贡献。受到@David Arenburg 的启发,我得到了以下信息。

    df <- data.frame(variable1 = c("var1", "var2", "var3"),
                     variable2 = c("var4", "var5", "var6"),
                     variable3 = c("var7", "var8", "var9"),
                     stringsAsFactors = FALSE) 
    
    library(dplyr)
    mutate_each(df, funs(combn(., 2, paste, collapse = "_")))
    
    #  variable1 variable2 variable3
    #1 var1_var2 var4_var5 var7_var8
    #2 var1_var3 var4_var6 var7_var9
    #3 var2_var3 var5_var6 var8_var9
    
    library(data.table)
    setDT(df)[, lapply(.SD, function(x) {combn(x, 2, paste, collapse = "_")})]
    
    #   variable1 variable2 variable3
    #1: var1_var2 var4_var5 var7_var8
    #2: var1_var3 var4_var6 var7_var9
    #3: var2_var3 var5_var6 var8_var9
    

    【讨论】:

    • @akrun 我不知道combn 实际上有一个函数。我试图将矩阵转换为数据中每一列的向量,但后来我卡住了。当我看到大卫使用combn 时,我想到了这些想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多