高级if / then / loop函数创建新列

时间:2018-05-05 03:57:02

标签: r loops

我正在学习R(专注于 tidyverse 包),并希望有人可以帮助我解决以下问题。

我有一个类似于以下内容的数据集:

library("tibble")
myData <- frame_data(
  ~id, ~r1, ~r2, ~r3, ~r4, ~r5, ~r6, ~r7, ~r8, ~r9, ~r10, ~r11, ~r12, ~r13, ~r14, ~r15, ~r16,
  "A", 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  "B", 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  "C", 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2,
  "D", 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2,
  "E", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
)

基本上,我有多行响应者数据,每个受访者给出了16个“1”或“2”的响应。

对于每个受访者(即每一行),我想创建另外三列:

第一个新列 - 名为“switchCount” - 标识受访者从“2”响应切换到“1”响应的次数。

第二个新列 - 名为“switch1” - 标识响应者从“2”响应切换到“1”响应的第一时间的索引。

第三个新列 - 名为“switch2” - 标识受访者从“2”响应切换到“1”响应时最终时间的索引。

如果没有开关且所有值都是“2”,则返回索引0。

如果没有开关且所有值均为“1”,则返回索引16。

因此,最终的数据表应如下所示:

myData <- frame_data(
  ~id, ~r1, ~r2, ~r3, ~r4, ~r5, ~r6, ~r7, ~r8, ~r9, ~r10, ~r11, ~r12, ~r13, ~r14, ~r15, ~r16, ~switchCount, ~switch1, ~switch2,
  "A", 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1,
  "B", 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4,
  "C", 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 3, 9,
  "D", 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 3, 6, 15,
  "E", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 16, 16
)

1 个答案:

答案 0 :(得分:0)

一种方法可以是逐行连接所有响应列,然后使用gregexpr

查找2,1的出现次数
library(dplyr)

myData %>%
  rowwise() %>%
  mutate(concat_cols = paste(r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,sep=";"),
         switchCount = ifelse(gregexpr("2;1", concat_cols)[[1]][1] == -1, 
                              0, 
                              length(gregexpr("2;1", concat_cols)[[1]])),
         switch1     = ifelse(switchCount == 0, 
                              ifelse(grepl("2",concat_cols), 1, 16),
                              min(floor(gregexpr("2;1", concat_cols)[[1]]/2)+1)),
         switch2     = ifelse(switchCount == 0, 
                              ifelse(grepl("2",concat_cols), 1, 16),
                              max(floor(gregexpr("2;1", concat_cols)[[1]]/2)+1)))  %>%
  select(-concat_cols)

输出为:

  id r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 switchCount switch1 switch2
1  A  2  2  2  2  2  2  2  2  2   2   2   2   2   2   2   2           0       1       1
2  B  2  2  2  2  1  1  1  1  1   1   1   1   1   1   1   1           1       4       4
3  C  2  2  2  1  1  1  2  2  2   1   1   1   1   2   2   2           2       3       9
4  D  1  1  2  2  2  2  1  1  2   2   1   1   1   2   2   1           3       6      15
5  E  1  1  1  1  1  1  1  1  1   1   1   1   1   1   1   1           0      16      16

示例数据:

myData <- structure(list(id = c("A", "B", "C", "D", "E"), r1 = c(2, 2, 
2, 1, 1), r2 = c(2, 2, 2, 1, 1), r3 = c(2, 2, 2, 2, 1), r4 = c(2, 
2, 1, 2, 1), r5 = c(2, 1, 1, 2, 1), r6 = c(2, 1, 1, 2, 1), r7 = c(2, 
1, 2, 1, 1), r8 = c(2, 1, 2, 1, 1), r9 = c(2, 1, 2, 2, 1), r10 = c(2, 
1, 1, 2, 1), r11 = c(2, 1, 1, 1, 1), r12 = c(2, 1, 1, 1, 1), 
    r13 = c(2, 1, 1, 1, 1), r14 = c(2, 1, 2, 2, 1), r15 = c(2, 
    1, 2, 2, 1), r16 = c(2, 1, 2, 1, 1), switchCount = c(0, 1, 
    2, 3, 0), switch1 = c(1, 4, 3, 6, 16), switch2 = c(1, 4, 
    9, 15, 16)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame"))