【问题标题】:Iterate over a subset of column names迭代列名的子集
【发布时间】:2017-02-22 12:18:48
【问题描述】:

我是 R 新手,但在这里我有一个包含多个条件的多个测量值的数据框,我想在相同条件的列上执行嵌套循环,测试它们是否有两个真实的测量值(不是零)至少,如果是这样,请计算新数据集中这些特定条件的平均值。

    > sample <- list(c(8,0,12,5,0,11), c(15,5,0,10,12,13), c(1,1,0,3,0,9), 
      c(11,9,8,0,4,7), c(12,5,5,0,9,0), c(1,7,2,0,8,0))
    > sample <- as.data.frame(sample)
    > colnames(sample) <- c("x.1","x.2","x.3","y.1","y.2","y.3")


   > sample
  x.1 x.2 x.3 y.1 y.2 y.3
1   8  15   1  11  12   1
2   0   5   1   9   5   7
3  12   0   0   8   5   2
4   5  10   3   0   0   0
5   0  12   0   4   9   8
6  11  13   9   7   0   0

我的输出数据集理想情况下应该是这样的:

> Newsample
   x y
1  8 8
2  2 7
3  0 5
4  6 0
5  0 7
6 11 0

【问题讨论】:

    标签: r loops for-loop nested dplyr


    【解决方案1】:

    我们定义f_rowmean函数:

    f_rowmean <- function(y) apply(y,1, function(x) ifelse(sum(x!=0)>=2, mean(x), 0))
    

    然后:

    data.frame(x=f_rowmean(sample[,grep("x", names(sample))]), 
               y=f_rowmean(sample[,grep("y", names(sample))]))
    
       # x y
    # 1  8 8
    # 2  2 7
    # 3  0 5
    # 4  6 0
    # 5  0 7
    # 6 11 0
    

    编辑

    至于OP的新问题陈述(在cmets中),假设你的数据集在df1,那么你可以这样做:

    res.cols <- c("CAOV-3 Reg", "CAOV-3 Mod", "OVCAR-3Reg", "OVCAR-4Reg", "VOA1056Reg", 
    "VOA4698Reg", "VOA4698Mod", "TOV112DReg", "TOV112DMod", "TOV21G Mod", 
    "HCC38 Reg", "HCC38 Mod")
    
    res <- setNames(data.frame(matrix(0,nrow(df1),length(res.cols))), res.cols)
    res <- sapply(res.cols, function(x) res[,x] <- f_rowmean(df1[,grep(x, names(df1))]))
    

    【讨论】:

    • 抱歉,我没有搞清楚这个,但我的数据集比上面这个虚拟示例大得多。它实际上由 38 个重复测量列组成,测量 13 个条件,所以我想创建一个循环贯穿整个数据帧以创建一个新数据帧,而不仅仅是 x 和 y 列表
    • 列名是:"CAOV-3 Reg.1" "CAOV-3 Reg.2" "CAOV-3 Reg.3" "CAOV-3 Mod.1" "CAOV-3 Mod .2" "CAOV-3 Mod.3" "OVCAR-3Reg.1" "OVCAR-3Reg.2" "OVCAR-3Reg.3" "OVCAR-4Reg.1" "OVCAR-4Reg.2" "OVCAR-4Reg .3" "VOA1056Reg.1" "VOA1056Reg.2" "VOA1056Reg.3" "VOA4698Reg.1" "VOA4698Reg.2" "VOA4698Reg.3" "VOA4698Mod.1" "VOA4698Mod.2" "VOA4698Mod.3" "TOV112DMod .1" "TOV112DMod.2" "TOV112DMod.3" "TOV21G Reg.1" "TOV21G Reg.2" "TOV21G Reg.3" "TOV21G Mod.1" "TOV21G Mod.2" "TOV21G Mod.3" " HCC38 Reg.1" "HCC38 Reg.2" "HCC38 Mod.1""HCC38 Mod.2" "HCC38 Mod.3"
    • 理想情况下我想创建一个数据框:
    • > y2 [1]“CAOV-3 Reg”“CAOV-3 Mod”“OVCAR-3Reg”“OVCAR-4Reg”“VOA1056Reg”“VOA4698Reg”“VOA4698Mod”[8]“TOV112DReg” "TOV112DMod" "TOV21G Mod" "HCC38 Reg" "HCC38 Mod"
    • 工作得非常好。谢谢!
    【解决方案2】:

    我们遍历list中'x'和'y'列的索引,得到逻辑矩阵的rowSums并使用ifelse得到rowMeans

    data.frame(setNames(lapply(list(grep("^x", names(sample)),
                              grep("^y", names(sample))), function(i) {
                             x1 <- sample[i]
                   ifelse(rowSums(x1!=0)>1, rowMeans(x1), 0)}), c("x", "y"))) 
    #   x y
    #1  8 8
    #2  2 7
    #3  0 5
    #4  6 0
    #5  0 7
    #6 11 0
    

    【讨论】:

    • 对不起,我没有把它弄清楚,但我的数据集比上面这个虚拟示例大得多。它实际上由 38 个重复测量列组成,测量 13 个条件,所以我想创建一个循环贯穿整个数据帧以创建一个新数据帧,而不仅仅是 x 和 y 列表
    • @Mohere 这个很容易改
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    相关资源
    最近更新 更多