我有一个非常大的DF,结构看起来像这样:
route_1 route_2 route_3 route_4 route_grey_1 route_grey_2
A B NA NA NA NA
A B C NA A NA
A B C D A D
A B C NA C NA
B C E F B C
但是,A,B,C,D
行之间会有所不同。
对于每一行,我试图找到route_grey_1和route_grey_2中未提及的route_1到route_4的两个值。
这将始终是2个值。 (如果route_n中只有两个值,则不会有route_grey_n值,如果route_n中有三个值,则route_grey_n中只有一个值,等等。)
所以上面的输入应该导致这个输出(添加两个新列:
route_1 route_2 route_3 route_4 route_grey_1 route_grey_2 result1 result2
A B NA NA NA NA A B
A B C NA A NA B C
A B C D A D B C
A B C NA C NA A B
B C E F B C E F
到目前为止,我想到的唯一解决方案是编写一个函数,遍历所有行并将一个接一个的route_n与route_grey_n进行比较。 首先,我认为可能有更好的解决方案,我希望循环非常慢。其次,我无法使我的循环工作,所以如果你认为这可能是唯一的解决方案,希望有人可以帮助我。
/ e:虽然大卫的答案适用于小型DF,但我的数据需要30分钟才会失败:
Error: cannot allocate vector of size 380 Kb
Error during wrapup: cannot allocate vector of size 438 Kb
我怀疑应该有使用dplyr或data.table包的解决方案。
/ e2:在玩了dplyr后,我设法找到了解决方案。它似乎工作,我的DF需要约30秒。然而,它非常hacky,可能不是一个非常好的。因此,我们非常感谢任何改进。这是我的代码:
df <- df %>% group_by(index) %>%
mutate( c_route1 = !route_1 %in% c(route_grey_1,route_grey_2),
c_route2 = !route_2 %in% c(route_grey_1,route_grey_2),
c_route3 = !route_3 %in% c(route_grey_1,route_grey_2),
c_route4 = !route_4 %in% c(route_grey_1,route_grey_2))
这会在df中创建具有逻辑的列,然后它变得丑陋(可能这部分可以做得更好,很想看到一些替代方案):
df$result1[df$c_route1] <- df$route_1[df$c_route1]
df$result1[!df$c_route1 & df$c_route2 ] <- df$route_2[ !df$c_route1 & df$c_route2 ]
df$result1[!df$c_route1 & !df$c_route2 ] <- df$route_3[ !df$c_route1 & !df$c_route2 ]
df$result2[df$c_route1 ] <- df$route_2[ df$c_route1 ]
df$result2[!df$c_route1 & df$c_route2 ] <- df$route_3[ !df$c_route1 & df$c_route2 ]
df$result2[!df$c_route1 & !df$c_route2 ] <- df$route_4[ !df$c_route1 & !df$c_route2 ]
答案 0 :(得分:1)
尽管我试图避免apply
,但这是我能想到的唯一解决方案
DF[c("result1", "result2")] <- t(apply(DF, 1, function(x) x[1:4][t(!(x[1:4] %in% x[5:6]))]))
# route_1 route_2 route_3 route_4 route_grey_1 route_grey_2 result1 result2
# 1 A B <NA> <NA> <NA> <NA> A B
# 2 A B C <NA> A <NA> B C
# 3 A B C D A D B C
# 4 A B C <NA> C <NA> A B
# 5 B C E F B C E F