如何在名称中具有特定字符串的一系列列上应用相同的函数?

时间:2013-09-09 22:08:24

标签: r function loops grep

我的数据框(dat)中有一个名为av1 av2 av3 ... av144的变量列表。我想将这些变量重新编码为另一系列变量,例如main1 main2 main3 ... main144:

dat$main1<-ifelse (dat$av1==5 or dat2$av1==8 or dat$av1==6,10,0)
dat$main2<-ifelse (dat$av2==5 or dat2$av2==8 or dat$av2==6,10,0)
#…
dat$main144<-ifelse (dat1$av144==5 or dat$av144==8 or dat$av144==6,10,0)

有人可以告诉我如何在不重写同一行144次的情况下将这个ifelse命令应用于两组变量?我试图通过列名提取“grep”但没有成功,但我认为我的方向错误......

非常感谢您提前,

2 个答案:

答案 0 :(得分:1)

现在经过轻微测试:

dat[gsub("av", "main", names(dat))] <- 
      lapply(dat[grep("av", names(dat))], 
            function(col) { ifelse (col==5 | col==8 | col==6, 10, 0) } )

SimonO101提供的数据集不像我预期的那样复杂。这是对我的代码稍微复杂但仍然合理的最小测试(现在我修复了第一个版本中缺少的逗号)和(修复了将行分配给列的逻辑错误):

  dat <- data.frame( one=1, two=2, av1 = sample(8) , av2 = sample(8) , av3 = sample(8) ); 

   dat <- cbind(dat,      sapply(dat[grep("av", names(dat))], 
              function(col) { ifelse (col==5 | col==8 | col==6, 10, 0) } ) )
 dat
 #----------------
  one two av1 av2 av3 av1 av2 av3
1   1   2   4   3   4   0   0   0
2   1   2   6   2   5  10   0  10
3   1   2   7   7   8   0   0  10
4   1   2   5   8   1  10  10   0
5   1   2   2   5   6   0  10  10
6   1   2   1   1   7   0   0   0
7   1   2   3   4   3   0   0   0
8   1   2   8   6   2  10  10   0
#--------------
 names( dat)[6:8] <- gsub("av", "main", names(dat)[6:8])
 dat
#-----------------
  one two av1 av2 av3 main1 main2 main3
1   1   2   4   3   4     0     0     0
2   1   2   6   2   5    10     0    10
3   1   2   7   7   8     0     0    10
4   1   2   5   8   1    10    10     0
5   1   2   2   5   6     0    10    10
6   1   2   1   1   7     0     0     0
7   1   2   3   4   3     0     0     0
8   1   2   8   6   2    10    10     0

答案 1 :(得分:0)

这是一种类似的方法,有一些可重复的数据用于说明目的。我在dat中找到满足条件的位置,并将结果df中的值更改为10。

set.seed(1)
dat <- data.frame( av1 = sample(8) , av2 = sample(8) , av3 = sample(8) )
#  av1 av2 av3
#1   3   6   6
#2   8   1   7
#3   4   2   3
#4   5   7   4
#5   1   3   5
#6   7   8   1
#7   2   4   2
#8   6   5   8


#  Initialise a df to hold results, fill with FALSE values (0)
out <- `[<-`(dat , , , 0 )

#  Find where values should be TRUE
ind <- sapply( dat , function(x) x %in% c( 5 , 6 , 8 ) )

#  Change to 10
out[ ind ] <- 10

#  Change names if desired
names(out) <- gsub( "av" , "main" , names(dat) )
#  main1 main2 main3
#1     0    10    10
#2    10     0     0
#3     0     0     0
#4    10     0     0
#5     0     0    10
#6     0    10     0
#7     0     0     0
#8    10    10    10