【问题标题】:Swapping values between two columns using data.table使用 data.table 在两列之间交换值
【发布时间】:2016-04-25 06:43:36
【问题描述】:

我一直在为将this question 转换为data.table 解决方案而烦恼。 (为简单起见,我将使用相同的数据集)
V2 == "b 我想交换V1 <-> V3 之间的列。

dt <- data.table(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1))
#V1 V2 V3
#1:  1  a  2
#2:  2  a  3
#3:  4  b  1

下面的代码将是data.frame 的有效解决方案,但是由于我使用data.table 时的挫败感,我没有意识到我现在决定为data.table 找到解决方案.

dt <- data.table(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1))
df <- as.data.frame(dt)
df[df$V2 == "b", c("V1", "V3")] <- df[df$V2 == "b", c("V3", "V1")] 
#  V1 V2 V3
#1  1  a  2
#2  2  a  3
#3  1  b  4

我尝试编写一个lapply 函数循环遍历我的目标交换列表,尝试缩小问题范围以仅替换一个值,尝试以不同方式调用列名,但均未成功。
这是我设法得到的最接近的尝试:

> dt[dt$V2 == "b", c("V1", "V3")] <- dt[dt$V2 == "b", c(V3, V1)]
#Warning messages:
#1: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1,  :
#  Supplied 2 items to be assigned to 1 items of column 'V1' (1 unused)
#2: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1,  :
#  Supplied 2 items to be assigned to 1 items of column 'V3' (1 unused)

我们怎样才能得到data.table的解决方案?

【问题讨论】:

    标签: r data.table swap


    【解决方案1】:

    我们可以试试

    dt[V2=="b", c("V3", "V1") := .(V1, V3)]
    

    【讨论】:

    • 我猜使用.SD 比通过list(V1, V3) 更快?
    • @BenBarnes 我没有测试它是否会更快,看起来list(V1, V3) 也可以。
    • @eddi,你对.SDcols 有什么看法?如果您有预定义列的向量,我认为这是更强大的解决方案。
    • @DavidArenburg 这是一个奇怪的问题 :) 如果使用得当,我对.SDcols 没有任何反对意见。在这种情况下,它所做的只是添加额外的符号来输入并使解决方案更加不透明。
    【解决方案2】:

    仅供娱乐。 @akruns 的解决方案显然更胜一筹。我推断我可以创建一个临时副本,进行条件交换,然后依次使用[.data.table 操作删除该副本:

     dt[, tv1 := V1][V2=="b", V1 := V3][V2=="b", V3 := tv1][ , tv1 := NULL]
    
    > dt
       V1 V2 V3
    1:  1  a  2
    2:  2  a  3
    3:  1  b  4
    

    【讨论】:

    • 啊,是的,我正在交换“a”值而不是“b”值。似乎不值得修复,因为它会很慢。我只是发布它,以便人们可以扔西红柿。
    • 如果你的目标是有趣,至少做一个bitwXor 解决方案;不开心
    • 我希望我知道bitwXor 是什么。我想我需要做一些搜索。
    猜你喜欢
    • 2018-08-17
    • 2011-12-06
    • 2019-02-28
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2017-06-17
    相关资源
    最近更新 更多