使用with或within更改data.frame中的值

时间:2014-08-24 16:25:38

标签: r

这个问题与以下内容有关: merging two files into a new file

dat1 <- structure(list(V1 = structure(1:6, .Label = c("1", "2", "3", 
 "4", "5", "6"), class = "factor"), V2 = structure(c(2L, 3L, 4L, 
 5L, 1L, 1L), .Label = c("1", "2", "3", "4", "5"), class = "factor"), 
V3 = structure(1:6, .Label = c("10", "20", "30", "40", "50", 
"60"), class = "factor")), .Names = c("V1", "V2", "V3"), class = "data.frame", row.names = c(NA, 
-6L))

 dat2 <- structure(list(V1 = structure(1:6, .Label = c("1", "2", "3", 
 "4", "5", "6"), class = "factor"), V2 = structure(c(5L, 2L, 3L, 
 4L, 1L, 6L), .Label = c("2", "3", "4", "5", "8", "80"), class = "factor"), 
V3 = structure(c(1L, 2L, 3L, 5L, 6L, 4L), .Label = c("10", 
"100", "45", "60", "78", "99"), class = "factor")), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -6L))

> dat1
  V1 V2 V3
1  1  2 10
2  2  3 20
3  3  4 30
4  4  5 40
5  5  1 50
6  6  1 60
> 
> dat2
  V1 V2  V3
1  1  8  10
2  2  3 100
3  3  4  45
4  4  5  78
5  5  2  99
6  6 80  60

合并了两个data.frame:

> res <- merge(dat1,dat2, by=c("V1", "V2"),all=TRUE)
> res
  V1 V2 V3.x V3.y
1  1  2   10 <NA>
2  1  8 <NA>   10
3  2  3   20  100
4  3  4   30   45
5  4  5   40   78
6  5  1   50 <NA>
7  5  2 <NA>   99
8  6  1   60 <NA>
9  6 80 <NA>   60
> 

如果V3.x为NA,如何使用或内部将值从V3.y转换到V3.x.我试过了:

> within(res[is.na(res$V3.x),], {V3.x = V3.y;V3.y=NA})
  V1 V2 V3.x V3.y
2  1  8   10   NA
7  5  2   99   NA
9  6 80   60   NA
> 

但是data.frame res没有改变。如何实现这一目标。谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

尝试:

 res[] <- lapply(res, function(x) as.numeric(as.character(x)))

 within(res, {indx <-is.na(V3.x)
              V3.x[indx]<- V3.y[indx]
              V3.y[indx|is.na(V3.y)] <- 0 #if it is need to convert to 0
               })[,-5]
  # V1 V2 V3.x V3.y
 #1  1  2   10    0
 #2  1  8   10    0
 #3  2  3   20  100
 #4  3  4   30   45
 #5  4  5   40   78
 #6  5  1   50    0
 #7  5  2   99    0
 #8  6  1   60    0
 #9  6 80   60    0

答案 1 :(得分:0)

您的解决方案不起作用,因为V3.xV3.y是因素,V3.y中的因子级别不一定与V3.x中的因子级别匹配。

如果您先转换为数字,那么您的解决方案是有效的。或者:

res2 <- within(res, {
  V3.x <- as.numeric(as.character(V3.x))
  V3.y <- as.numeric(as.character(V3.y))
  V3.x[is.na(V3.x)] <- V3.y[is.na(V3.x)]})

结果:

> res2
  V1 V2 V3.x V3.y
1  1  2   10   NA
2  1  8   10   10
3  2  3   20  100
4  3  4   30   45
5  4  5   40   78
6  5  1   50   NA
7  5  2   99   99
8  6  1   60   NA
9  6 80   60   60