我在R中有一个非常简单的疑问,但我仍然无法在以前的答案中找到我需要的解决方案,或者我错过了它。我想要一种vlookup(如Excel)公式,但仅适用于数据框中的特定行。假设我有一个如下数据框:
id obs year a1 a2 b1 b2 c
604 43 2003 NA NA NA NA NA
605 43 2004 NA NA NA NA NA
606 43 2005 9000 6421 1748365 0.1616 36872152
769 55 2003 NA NA NA NA NA
770 55 2004 NA NA NA NA NA
771 55 2005 2500 12449 NA NA 125992307
844 61 2003 1800 11633 157977428 0.0089 69901689
845 61 2004 2200 14841 228966763 0.0012 86853166
846 61 2005 2500 15559 345889717 0.0081 103029905
2209 178 2003 NA NA NA NA NA
2210 178 2004 200 45093 NA NA 11668685
2211 178 2005 250 47202 610500 0.1605 12813908
然后,我将一个公式应用于数据中的所有完整案例,因此,对于这个特定的例子,我将得到一个矩阵,其中包含5行结果(每次观察2个结果),我在这里显示:
id x y
606 8000 30
844 1700 90
845 8000 61
846 400 82
2211 600 30
所以现在,我基本上想要的是,仅对于数据框中2005年的行,检查矩阵中匹配(通过id)的位置并修改数据框中的特定列(我之前创建的“值“)及其对应的结果在矩阵的”y“列中。在这里考虑一些要点:(a)对于非完整案例,它应提供NA,(b)我只希望修改2005年;其他年份将随后使用其他后续公式进行修改,这些公式将提供不同的矩阵结果。鉴于此,据我所知,merge
,match
,cbind
或plyr
等函数会影响整个列,我不是在寻找它。其他选项如%in%
或%l%
也不起作用,或者我错误地使用它们。这是我到目前为止所尝试的并没有成功:
df$value [c(df$year==2005)] <- matrix[,3[matrix[,1]==df$id]]
df$value [c(df$year==2005)] <- matrix[,3][matrix[,1]==df$id]
也许循环可以成为解决方案,但我仍然在学习如何构建它们并且也是无用的。 这是我期望的结果,以便更好地理解。
id obs year a1 a2 b1 b2 c value
604 43 2003 NA NA NA NA NA NA
605 43 2004 NA NA NA NA NA NA
606 43 2005 9000 6421 1748365 0.1616 36872152 30
769 55 2003 NA NA NA NA NA NA
770 55 2004 NA NA NA NA NA NA
771 55 2005 2500 12449 NA NA 125992307 NA
844 61 2003 1800 11633 157977428 0.0089 69901689 NA
845 61 2004 2200 14841 228966763 0.0012 86853166 NA
846 61 2005 2500 15559 345889717 0.0081 103029905 82
2209 178 2003 NA NA NA NA NA NA
2210 178 2004 200 45093 NA NA 11668685 NA
2211 178 2005 250 47202 610500 0.1605 12813908 30
非常感谢任何提示并继续做好工作。我已经检查了这个网络大约一年了,它给了我很多帮助!!!
答案 0 :(得分:2)
使用akrun的数据,你也可以使用:
ifelse(df1$year == 2005 & rowSums(sapply(df1[-(1:3)], is.na)) == 0,
m1[match(df1$id, m1[, "id"]), "y"],
NA)
#[1] NA NA 30 NA NA NA NA NA 82 NA NA 30
即。如果年份是2005年并且行中没有NA
,请从矩阵中取相应的“y”NA
。
答案 1 :(得分:1)
您可以尝试:df1
是data.frame
和m1
矩阵
indx <- which(df1$year==2005)
我想我错过了其中一个条件,即complete.cases
(尽管在示例数据集中,它没有改变结果)。新indx
应为
indx <- which(df1$year==2005 & !rowSums(is.na(df1[-(1:3)]))) #inspired from @alexis_laz answer
df1$value <- NA
df1$value[indx[df1$id[indx] %in% m1[,"id"] ]] <- m1[, "y"][m1[,"id"] %in% df1$id[indx]]
df1
# id obs year a1 a2 b1 b2 c value
#1 604 43 2003 NA NA NA NA NA NA
#2 605 43 2004 NA NA NA NA NA NA
#3 606 43 2005 9000 6421 1748365 0.1616 36872152 30
#4 769 55 2003 NA NA NA NA NA NA
#5 770 55 2004 NA NA NA NA NA NA
#6 771 55 2005 2500 12449 NA NA 125992307 NA
#7 844 61 2003 1800 11633 157977428 0.0089 69901689 NA
#8 845 61 2004 2200 14841 228966763 0.0012 86853166 NA
#9 846 61 2005 2500 15559 345889717 0.0081 103029905 82
#10 2209 178 2003 NA NA NA NA NA NA
#11 2210 178 2004 200 45093 NA NA 11668685 NA
#12 2211 178 2005 250 47202 610500 0.1605 12813908 30
df1 <- structure(list(id = c(604L, 605L, 606L, 769L, 770L, 771L, 844L,
845L, 846L, 2209L, 2210L, 2211L), obs = c(43L, 43L, 43L, 55L,
55L, 55L, 61L, 61L, 61L, 178L, 178L, 178L), year = c(2003L, 2004L,
2005L, 2003L, 2004L, 2005L, 2003L, 2004L, 2005L, 2003L, 2004L,
2005L), a1 = c(NA, NA, 9000L, NA, NA, 2500L, 1800L, 2200L, 2500L,
NA, 200L, 250L), a2 = c(NA, NA, 6421L, NA, NA, 12449L, 11633L,
14841L, 15559L, NA, 45093L, 47202L), b1 = c(NA, NA, 1748365L,
NA, NA, NA, 157977428L, 228966763L, 345889717L, NA, NA, 610500L
), b2 = c(NA, NA, 0.1616, NA, NA, NA, 0.0089, 0.0012, 0.0081,
NA, NA, 0.1605), c = c(NA, NA, 36872152L, NA, NA, 125992307L,
69901689L, 86853166L, 103029905L, NA, 11668685L, 12813908L)), .Names = c("id",
"obs", "year", "a1", "a2", "b1", "b2", "c"), class = "data.frame", row.names = c(NA,
-12L))
m1 <- structure(c(606L, 844L, 845L, 846L, 2211L, 8000L, 1700L, 8000L,
400L, 600L, 30L, 90L, 61L, 82L, 30L), .Dim = c(5L, 3L), .Dimnames = list(
NULL, c("id", "x", "y")))
答案 2 :(得分:0)
如果我在你的鞋子里,我可能会编写一个for循环和一个循环遍历每条记录的函数,因为看起来他们根据条件会有几个不同的逻辑。
以下是我对您的“规范”的理解:
affecting the whole column
。这是一些代码,它有点长,但我不知道是否将数据框分成两部分,然后使用melt / cast将它们重新组合在一起的想法将有所帮助:
mytext1 <- "id obs year a1 a2 b1 b2 c
604 43 2003 NA NA NA NA NA
605 43 2004 NA NA NA NA NA
606 43 2005 9000 6421 1748365 0.1616 36872152
769 55 2003 NA NA NA NA NA
770 55 2004 NA NA NA NA NA
771 55 2005 2500 12449 NA NA 125992307
844 61 2003 1800 11633 157977428 0.0089 69901689
845 61 2004 2200 14841 228966763 0.0012 86853166
846 61 2005 2500 15559 345889717 0.0081 103029905
2209 178 2003 NA NA NA NA NA
2210 178 2004 200 45093 NA NA 11668685
2211 178 2005 250 47202 610500 0.1605 12813908"
mytext2 <- "id x y
606 8000 30
844 1700 90
845 8000 61
846 400 82
2211 600 30"
data.1 <- read.table(text=mytext1, header=TRUE)
data.2 <- read.table(text=mytext2, header=TRUE)
require(plyr)
require(reshape2)
a <- merge(x=subset(data.1, year==2005), y=data.2, by="id")
b <- subset(data.1, year!=2005)
a.new <- melt(a, id.vars=c('id'))
b.new <- melt(b, id.vars=c('id'))
result.new <- rbind(a.new, b.new)
result <- dcast(result.new, id ~ variable)
现在您的结果如下:
> result
id obs year a1 a2 b1 b2 c x y
1 604 43 2003 NA NA NA NA NA NA NA
2 605 43 2004 NA NA NA NA NA NA NA
3 606 43 2005 9000 6421 1748365 0.1616 36872152 8000 30
4 769 55 2003 NA NA NA NA NA NA NA
5 770 55 2004 NA NA NA NA NA NA NA
6 844 61 2003 1800 11633 157977428 0.0089 69901689 NA NA
7 845 61 2004 2200 14841 228966763 0.0012 86853166 NA NA
8 846 61 2005 2500 15559 345889717 0.0081 103029905 400 82
9 2209 178 2003 NA NA NA NA NA NA NA
10 2210 178 2004 200 45093 NA NA 11668685 NA NA
11 2211 178 2005 250 47202 610500 0.1605 12813908 600 30
你仍然需要在最后或在将它们重新组合之前更改名称..:)