使用来自其他数据框的 column/row 名称的匹配项进行条件替换
conditional replace using match of column/row names from other data frame
我有两个数据框:
id <- c("a", "b", "c")
a <- 0
b <- 0
c <- 0
df1 <- data.frame(id, a, b, c)
id a b c
1 a 0 0 0
2 b 0 0 0
3 c 0 0 0
num <- c("a", "c", "c")
partner <- c("b", "b", "a")
value <- c("10", "20", "30")
df2 <- data.frame(num, partner, value)
num partner value
1 a b 10
2 c b 20
3 c a 30
我想在每个实例 df1$id==df2$num & colnames(df1)==df2$partner
中用 df2$value
替换 df1
中的零。所以输出应该是这样的:
a <- c(0, 0, 30)
b <- c(10, 0, 20)
c <- c(0, 0, 0)
df.nice <- data.frame(id, a, b, c)
id a b c
1 a 0 10 0
2 b 0 0 0
3 c 30 20 0
我可以用以下内容替换单个单元格:
df1$b[df1$id=="a"] <- ifelse(df2$num=="a" & df2$partner=="b", df2$value, 0)
但我需要为大型数据框遍历所有可能的 df1
row/column 组合。我怀疑这涉及 plyr 和 match 在一起,但不太清楚如何。
更新
感谢@MikeH.,我已经转向使用重塑。这似乎有效:
df.nice <- melt(df2, id=c("num", "partner"))
df.nice <- dcast(test.nice, num ~ partner, value.var="value")
制作这个:
num a b
1 a <NA> 10
2 c 30 20
我确实需要所有可能的 row/column 组合,但是,所有组合都表示为零。有没有办法要求重塑从另一个数据框(例如 df1)获取行和列,或者我应该在重塑后绑定它们吗?
如果你想要替换(而不是重塑),我认为一个简单的基础 R 解决方案是:
idxs <- t(mapply(cbind, match(df2$num, df1$id), match(df2$partner, names(df1))))
df1[idxs] <- df2$value
df1
id a b c
1 a 0 10 0
2 b 0 0 0
3 c 30 20 0
请注意,我构建了 row/column 组合查找以使用 t(mapply(...))
进行替换。当您 select 喜欢 df1[idxs]
时,它会转换为矩阵(转换为 select 特定的 row/column 组合),然后转换回 data.frame
.
我必须使用 stringsAsFactors = FALSE
读取您的数据,以便正确注册值(而不是数字)。
数据:
df2 <- data.frame(num, partner, value, stringsAsFactors = F)
df1 <- data.frame(id, a, b, c, stringsAsFactors = F)
我有两个数据框:
id <- c("a", "b", "c")
a <- 0
b <- 0
c <- 0
df1 <- data.frame(id, a, b, c)
id a b c
1 a 0 0 0
2 b 0 0 0
3 c 0 0 0
num <- c("a", "c", "c")
partner <- c("b", "b", "a")
value <- c("10", "20", "30")
df2 <- data.frame(num, partner, value)
num partner value
1 a b 10
2 c b 20
3 c a 30
我想在每个实例 df1$id==df2$num & colnames(df1)==df2$partner
中用 df2$value
替换 df1
中的零。所以输出应该是这样的:
a <- c(0, 0, 30)
b <- c(10, 0, 20)
c <- c(0, 0, 0)
df.nice <- data.frame(id, a, b, c)
id a b c
1 a 0 10 0
2 b 0 0 0
3 c 30 20 0
我可以用以下内容替换单个单元格:
df1$b[df1$id=="a"] <- ifelse(df2$num=="a" & df2$partner=="b", df2$value, 0)
但我需要为大型数据框遍历所有可能的 df1
row/column 组合。我怀疑这涉及 plyr 和 match 在一起,但不太清楚如何。
更新
感谢@MikeH.,我已经转向使用重塑。这似乎有效:
df.nice <- melt(df2, id=c("num", "partner"))
df.nice <- dcast(test.nice, num ~ partner, value.var="value")
制作这个:
num a b
1 a <NA> 10
2 c 30 20
我确实需要所有可能的 row/column 组合,但是,所有组合都表示为零。有没有办法要求重塑从另一个数据框(例如 df1)获取行和列,或者我应该在重塑后绑定它们吗?
如果你想要替换(而不是重塑),我认为一个简单的基础 R 解决方案是:
idxs <- t(mapply(cbind, match(df2$num, df1$id), match(df2$partner, names(df1))))
df1[idxs] <- df2$value
df1
id a b c
1 a 0 10 0
2 b 0 0 0
3 c 30 20 0
请注意,我构建了 row/column 组合查找以使用 t(mapply(...))
进行替换。当您 select 喜欢 df1[idxs]
时,它会转换为矩阵(转换为 select 特定的 row/column 组合),然后转换回 data.frame
.
我必须使用 stringsAsFactors = FALSE
读取您的数据,以便正确注册值(而不是数字)。
数据:
df2 <- data.frame(num, partner, value, stringsAsFactors = F)
df1 <- data.frame(id, a, b, c, stringsAsFactors = F)