使用「;我";在for循环中,将函数应用于某些列

使用「;我";在for循环中,将函数应用于某些列,r,for-loop,data.table,R,For Loop,Data.table,我使用for(I in cols)循环遍历列表cols=c(“x”、“y”、“z”),但是: 使用“:=”创建新列时,我无法将“I”用作列的名称 我创建mode_func是为了获取向量中最频繁的字符串,但是当我使用lappy时,“I”似乎不作为列 有人能帮我理解for循环中的问题和“i”的动态吗?非常感谢 set.seed(10) 假人=数据表(id=c(“11”、“11”、“11”、“22”、“22”、“33”、“33”、“33”), x=样品(c(“a”、“b”、“c”),10,替换为T),

我使用for(I in cols)循环遍历列表cols=c(“x”、“y”、“z”),但是:

  • 使用“:=”创建新列时,我无法将“I”用作列的名称
  • 我创建mode_func是为了获取向量中最频繁的字符串,但是当我使用lappy时,“I”似乎不作为列
  • 有人能帮我理解for循环中的问题和“i”的动态吗?非常感谢

    set.seed(10)
    假人=数据表(id=c(“11”、“11”、“11”、“22”、“22”、“33”、“33”、“33”),
    x=样品(c(“a”、“b”、“c”),10,替换为T),
    y=样品(c(“a”、“b”、“c”),10,替换为T),
    z=样品(c(“a”、“b”、“c”),10,替换为T),
    i=样品(3,10,替换=T),
    j=样品(3,10,替换=T),
    k=样品(3,10,替换=T))
    
    mode_func您可以使用
    lappy
    cols
    上直接调用
    mode_func

    library(data.table)
    dummy[, (cols) := lapply(.SD, mode_func), by = "id"]
    
    dummy
    #    id x y z
    # 1: 11 b b c
    # 2: 11 b b c
    # 3: 11 b b c
    # 4: 22 a b b
    # 5: 22 a b b
    # 6: 22 a b b
    # 7: 33 a a c
    # 8: 33 a a c
    # 9: 33 a a c
    #10: 33 a a c
    

    就运行
    for
    循环而言,当您为每个列分别调用
    mode_func
    函数时,您需要使用
    .SDcols
    对特定列进行子集划分,并将
    .SD
    值作为每次迭代的函数输入。(感谢@David Arenburg的评论)


    我们可以从
    dplyr

    library(dplyr)
    dummy %>% 
        group_by(id) %>% 
        mutate_at(vars(cols), mode_func)
    

    谢谢,它工作得很好,但是,我渴望了解“我”在for循环中是如何交互的。顺便说一句,我也试着用你们提供的类似方法对一些列求平均值,你们能帮我解决我得到的错误吗?我在虚拟表中包括了新的列I、j、k。非常感谢你@Thomasun David(在评论中)很好地解释了您尝试
    for
    循环的问题。他还解释了你的第二次尝试。假设您有数字列,您可以创建新列来存储它们。为了运行循环,您可以对(i In cols)dummy[,(i):=mode\u func(.SD),.SDcols=i,by=id]执行
    。关于第二次尝试中的错误,它只是类型不匹配。您的代码很好,但您正在尝试使用double by group覆盖整数列。因此,有一个阶段,列的一部分仍然是整数(1,2,3),它的一部分变成了双精度(例如,2.5),并且R不能有一个包含两个类的列。您可以通过创建新列来说明这一点,例如,
    dummy[,paste0(cols,“_-mean”):=lapply(.SD,mean,na.rm=TRUE),.SDcols=cols,by=id]
    在使用列名作为索引时也应该小心,因为它会造成环境混乱。你们两个都有一个名为
    i
    的列,并且在
    i
    上运行循环。这将打乱函数,如
    mget/get
    。因此,如果将
    i
    替换为
    a
    ,您还可以对(cols中的a)dummy[,(a):=mode_func(get(a)),by=id]执行
    。您不能只运行
    mode\u func(i)
    的原因是data.table在j中进行非标准求值,因此它希望列名不带引号-例如
    i
    而不是
    “i”
    。非常感谢您的详细解释和解决方案!祝你度过愉快的一天,来自巴塞罗那的问候:)
    for (i in cols){
       dummy[, (i) := mode_func(.SD), by = "id", .SDcols = i]
    }
    
    library(dplyr)
    dummy %>% 
        group_by(id) %>% 
        mutate_at(vars(cols), mode_func)