Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在R中为每列添加不同条件的多列?_R_Dataframe_Multiple Columns - Fatal编程技术网

如何在R中为每列添加不同条件的多列?

如何在R中为每列添加不同条件的多列?,r,dataframe,multiple-columns,R,Dataframe,Multiple Columns,这是我的数据集。我想用5不同的条件向mydata添加5新列 mydata=data.frame(sub=rep(c(1:4),c(3,4,5,5)),t=c(1:3,1:4,1:5,1:5), y.val=c(10,20,13, 5,7,8,0, 45,17,25,12,10, 40,0,0,5,8

这是我的数据集。我想用
5
不同的条件向
mydata
添加
5
新列

mydata=data.frame(sub=rep(c(1:4),c(3,4,5,5)),t=c(1:3,1:4,1:5,1:5),
                      y.val=c(10,20,13,
                          5,7,8,0,
                          45,17,25,12,10,
                          40,0,0,5,8))
mydata
   sub t y.val
1    1 1    10
2    1 2    20
3    1 3    13
4    2 1     5
5    2 2     7
6    2 3     8
7    2 4     0
8    3 1    45
9    3 2    17
10   3 3    25
11   3 4    12
12   3 5    10
13   4 1    40
14   4 2     0
15   4 3     0
16   4 4     5
17   4 5     8
我想添加以下
5(最多't'列)
列作为

mydata$It1=ifelse(mydata$t==1 & mydata$y.val>0,1,0)
mydata$It2=ifelse(mydata$t==2 & mydata$y.val>0,1,0)
mydata$It3=ifelse(mydata$t==3 & mydata$y.val>0,1,0)
mydata$It4=ifelse(mydata$t==4 & mydata$y.val>0,1,0)
mydata$It5=ifelse(mydata$t==5 & mydata$y.val>0,1,0)
以下是预期结果

> mydata
   sub t y.val It1 It2 It3 It4 It5
1    1 1    10   1   0   0   0   0
2    1 2    20   0   1   0   0   0
3    1 3    13   0   0   1   0   0
4    2 1     5   1   0   0   0   0
5    2 2     7   0   1   0   0   0
6    2 3     8   0   0   1   0   0
7    2 4     0   0   0   0   0   0
8    3 1    45   1   0   0   0   0
9    3 2    17   0   1   0   0   0
10   3 3    25   0   0   1   0   0
11   3 4    12   0   0   0   1   0
12   3 5    10   0   0   0   0   1
13   4 1    40   1   0   0   0   0
14   4 2     0   0   0   0   0   0
15   4 3     0   0   0   0   0   0
16   4 4     5   0   0   0   1   0
17   4 5     8   0   0   0   0   1

如果可以使用for循环或任何其他技术将其编写为函数,我将非常感谢您的帮助

您可以使用
sapply
/
lappy

n <- seq_len(5)
mydata[paste0("It", n)] <- +(sapply(n, function(x) mydata$t==x & mydata$y.val>0))
mydata

#   sub t y.val It1 It2 It3 It4 It5
#1    1 1    10   1   0   0   0   0
#2    1 2    20   0   1   0   0   0
#3    1 3    13   0   0   1   0   0
#4    2 1     5   1   0   0   0   0
#5    2 2     7   0   1   0   0   0
#6    2 3     8   0   0   1   0   0
#7    2 4     0   0   0   0   0   0
#8    3 1    45   1   0   0   0   0
#9    3 2    17   0   1   0   0   0
#10   3 3    25   0   0   1   0   0
#11   3 4    12   0   0   0   1   0
#12   3 5    10   0   0   0   0   1
#13   4 1    40   1   0   0   0   0
#14   4 2     0   0   0   0   0   0
#15   4 3     0   0   0   0   0   0
#16   4 4     5   0   0   0   1   0
#17   4 5     8   0   0   0   0   1

n0
根据条件返回逻辑值
TRUE
/
FALSE
+
将这些逻辑值分别更改为1/0。(请尝试
+c(FALSE,TRUE)
)。它避免使用
ifelse
,即
ifelse(条件,1,0)

这里有一个整洁的解决方案,使用
pivot\u wide

library(tidyverse)

mydata %>%
  mutate(new_col = paste0("It", t),
         y_test = as.integer(y.val > 0)) %>%
  pivot_wider(id_cols = c(sub, t, y.val),
              names_from = new_col,
              values_from = y_test,
              values_fill = list(y_test = 0))

     sub     t y.val   It1   It2   It3   It4   It5
   <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1     1     1    10     1     0     0     0     0
 2     1     2    20     0     1     0     0     0
 3     1     3    13     0     0     1     0     0
 4     2     1     5     1     0     0     0     0
 5     2     2     7     0     1     0     0     0
 6     2     3     8     0     0     1     0     0
 7     2     4     0     0     0     0     0     0
 8     3     1    45     1     0     0     0     0
 9     3     2    17     0     1     0     0     0
10     3     3    25     0     0     1     0     0
11     3     4    12     0     0     0     1     0
12     3     5    10     0     0     0     0     1
13     4     1    40     1     0     0     0     0
14     4     2     0     0     0     0     0     0
15     4     3     0     0     0     0     0     0
16     4     4     5     0     0     0     1     0
17     4     5     8     0     0     0     0     1
库(tidyverse)
mydata%>%
突变(new_col=paste0(“It”,t),
y_test=as.integer(y.val>0))%>%
枢轴较宽(id\u cols=c(sub,t,y.val),
名称从=新列,
值从=y检验,
值\u填充=列表(y\u测试=0))
子t y.val It1 It2 It3 It4 It5
1     1     1    10     1     0     0     0     0
2     1     2    20     0     1     0     0     0
3     1     3    13     0     0     1     0     0
4     2     1     5     1     0     0     0     0
5     2     2     7     0     1     0     0     0
6     2     3     8     0     0     1     0     0
7     2     4     0     0     0     0     0     0
8     3     1    45     1     0     0     0     0
9     3     2    17     0     1     0     0     0
10     3     3    25     0     0     1     0     0
11     3     4    12     0     0     0     1     0
12     3     5    10     0     0     0     0     1
13     4     1    40     1     0     0     0     0
14     4     2     0     0     0     0     0     0
15     4     3     0     0     0     0     0     0
16     4     4     5     0     0     0     1     0
17     4     5     8     0     0     0     0     1
说明:

  • 创建两列,
    new\u col
    (新列名加上“It”)和
    y\u test
    y.val
    >0)
  • 将新列的值透视到列名中
  • 用零填充
    NA

这里是另一种方法,它基于将模型矩阵乘以逻辑
y.val>0

df <- cbind(mydata[1:3], model.matrix(~ factor(t) + 0, mydata)*(mydata$y.val>0))
要清除名称,可以执行以下操作:

names(df) <- sub("factor.t.", "It", names(df), fixed = TRUE)

names(df)一个
purrr
dplyr
选项可以是:

map_dfc(.x = 1:5,
        ~ mydata %>%
         mutate(!!paste0("It", .x) := as.integer(t == .x & y.val > 0)) %>%
         select(starts_with("It"))) %>%
 bind_cols(mydata)

   It1 It2 It3 It4 It5 sub t y.val
1    1   0   0   0   0   1 1    10
2    0   1   0   0   0   1 2    20
3    0   0   1   0   0   1 3    13
4    1   0   0   0   0   2 1     5
5    0   1   0   0   0   2 2     7
6    0   0   1   0   0   2 3     8
7    0   0   0   0   0   2 4     0
8    1   0   0   0   0   3 1    45
9    0   1   0   0   0   3 2    17
10   0   0   1   0   0   3 3    25
11   0   0   0   1   0   3 4    12
12   0   0   0   0   1   3 5    10
13   1   0   0   0   0   4 1    40
14   0   0   0   0   0   4 2     0
15   0   0   0   0   0   4 3     0
16   0   0   0   1   0   4 4     5
17   0   0   0   0   1   4 5     8
或者,如果要根据t列中的范围动态执行此操作:

map_dfc(.x = reduce(as.list(range(mydata$t)), `:`),
        ~ mydata %>%
         mutate(!!paste0("It", .x) := as.integer(t == .x & y.val > 0)) %>%
         select(starts_with("It"))) %>%
 bind_cols(mydata)

您可以使用
sapply
比较每个
t
是否与
1:5
相等,并将其与
y.val>0的
相结合

df <- cbind(mydata[1:3], model.matrix(~ factor(t) + 0, mydata)*(mydata$y.val>0))
within(mydata, It <- +(sapply(1:5, `==`, t) & y.val>0))
#   sub t y.val It.1 It.2 It.3 It.4 It.5
#1    1 1    10    1    0    0    0    0
#2    1 2    20    0    1    0    0    0
#3    1 3    13    0    0    1    0    0
#4    2 1     5    1    0    0    0    0
#5    2 2     7    0    1    0    0    0
#6    2 3     8    0    0    1    0    0
#7    2 4     0    0    0    0    0    0
#8    3 1    45    1    0    0    0    0
#9    3 2    17    0    1    0    0    0
#10   3 3    25    0    0    1    0    0
#11   3 4    12    0    0    0    1    0
#12   3 5    10    0    0    0    0    1
#13   4 1    40    1    0    0    0    0
#14   4 2     0    0    0    0    0    0
#15   4 3     0    0    0    0    0    0
#16   4 4     5    0    0    0    1    0
#17   4 5     8    0    0    0    0    1
内(mydata,It 0))
#子t y.val It.1 It.2 It.3 It.4 It.5
#1    1 1    10    1    0    0    0    0
#2    1 2    20    0    1    0    0    0
#3    1 3    13    0    0    1    0    0
#4    2 1     5    1    0    0    0    0
#5    2 2     7    0    1    0    0    0
#6    2 3     8    0    0    1    0    0
#7    2 4     0    0    0    0    0    0
#8    3 1    45    1    0    0    0    0
#9    3 2    17    0    1    0    0    0
#10   3 3    25    0    0    1    0    0
#11   3 4    12    0    0    0    1    0
#12   3 5    10    0    0    0    0    1
#13   4 1    40    1    0    0    0    0
#14   4 2     0    0    0    0    0    0
#15   4 3     0    0    0    0    0    0
#16   4 4     5    0    0    0    1    0
#17   4 5     8    0    0    0    0    1

@Uddin用一些解释更新了答案。