使用ddply和gsub来更改多个字符

时间:2014-09-19 00:15:14

标签: r dataframe plyr gsub

我已经采用了这种手动方式,但我想知道应该有一种更好的方法来使用gsub和ddply更改信息。

我有一个包含2列的数据框。第一个是用户ID,我不想触摸,第二个是填充了与活动相关的数字的列。我想更改其相应活动的编号。让我们说我的df是:

df <- data.frame(ID = rep(c(1, 2, 3), each = 3), act = rep(c(1, 2, 3), 3)

相关活动是:

acdf <- data.frame(num = c(1, 2, 3), actname = c("run", "walk", "fly"))

我的实际dfs更大但这对我的例子有效。我想过使用gsub将数字更改为实际名称,但我是这样做的,因为我不确定如何使用ddply:

df$act <- gsub("1", acdf[1, 2], df$act)
df$act <- gsub("2", acdf[2, 2], df$act)
df$act <- gsub("3", acdf[3, 2], df$act)

我的数据框应如下所示:

ID    act
1    run
1    walk
1    fly
2    run
2    walk
2    fly
3    run
3    walk
3    fly

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

使用合并

merge(df, acdf, by.x='act', by.y = 'num')

dplyr方法

names(acdf)[1] <- 'act'

library(dplyr)
df%>%
  inner_join(acdf)

导致

Joining by: "act"
  ID act actname
#1  1   1     run
#2  1   2    walk
#3  1   3     fly
#4  2   1     run
#5  2   2    walk
#6  2   3     fly
#7  3   1     run
#8  3   2    walk
#9  3   3     fly

具有超快的data.table,无需更改列名

library(data.table)
dt <- data.table(df, key = 'act')
dtacdf <- data.table(acdf, key = 'num') # original acdf

dt[dtacdf, nomatch = 0]

#   act ID actname
#1:   1  1     run
#2:   1  2     run
#3:   1  3     run
#4:   2  1    walk
#5:   2  2    walk
#6:   2  3    walk
#7:   3  1     fly
#8:   3  2     fly
#9:   3  3     fly

答案 1 :(得分:1)

或者您可以使用match

 df$act <- acdf$actname[match(df$act, acdf$num)]
 df
 #  ID  act
 #1  1  run
 #2  1 walk
 #3  1  fly
 #4  2  run
 #5  2 walk
 #6  2  fly
 #7  3  run
 #8  3 walk
 #9  3  fly

如果您想使用gsub,可以尝试mgsub

中的qdap
 library(qdap)

使用其他数据集:

  set.seed(42)
  df <- data.frame(ID = rep(1:3, each=4), act = sample(1:3, 12,replace=TRUE))

   with(acdf, mgsub(num, actname, df$act))
   #[1] "fly"  "fly"  "run"  "fly"  "walk" "walk" "fly"  "run"  "walk" "fly" 
   #[11] "walk" "fly" 

   df$act
   #[1] 3 3 1 3 2 2 3 1 2 3 2 3