【问题标题】:Padding Zeros to one column in all data frames in a list将零填充到列表中所有数据框中的一列
【发布时间】:2016-03-14 18:43:27
【问题描述】:

我有一个包含四个数据框的列表。每个数据框都有相同的第一列 person.id(每个数据框的唯一键)我想填充零。

问题:

代码运行但输出到控制台并且不会更改列表中的实际数据帧。

示例数据:

df1 <- data.frame(person.id = 3200:3214, letter = letters[1:15])
df2 <- data.frame(person.id = 4100:4114, letter = letters[8:22])
df3 <- data.frame(person.id = 4300:4314, letter = letters[10:24])
df4 <- data.frame(person.id = 5500:5514, letter = letters[5:19])
dataList <- list(df1, df2, df3, df4)

lapply(dataList, function(i){
  i$person.id <- str_pad(i$person.id, 6, pad = "0")
})

# Console output pads the zeros (not expected): 
[[1]]
 [1] "003200" "003201" "003202" "003203" "003204" "003205" "003206" "003207" "003208"
[10] "003209" "003210" "003211" "003212" "003213" "003214"

# Data Frames in list return with no change:

> dataList[[1]]$person.id
[1] 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214

如何将更改应用于列表中每个数据框中的每个列名称 person.id?

我想要的是在列表中的每个数据框中填充零:

> dataList[[1]]$person.id
 [1] 003200 003201 003202 003203 003204 003205 003206 003207 003208
[10] 003209 003210 003211 003212 003213 003214

【问题讨论】:

  • 你也可以在lapply中使用sprintf("%06d", i$person.id)代替str_pad
  • 我使用过 sprintf 并看到它有多快,但对于我的数据集,它低于 50,000 条记录,我不需要提高速度。好建议!

标签: r list dataframe


【解决方案1】:

lapply的函数需要返回完整的数据框。您使用的函数只返回赋值的结果,它只是列的值,而不是整个数据框。您还需要保存结果。这里我们使用transform作为修改数据框的函数,并使用person.id参数修改person.id列(参见?transform):

df.pad <- lapply(dataList, transform, person.id=str_pad(person.id, 6, pad = "0"))

然后,df.pad[[1]]: 产生:

[[1]]
   person.id letter
1     003200      a
2     003201      b
3     003202      c
4     003203      d
5     003204      e
6     003205      f
7     003206      g
8     003207      h
9     003208      i
10    003209      j
11    003210      k
12    003211      l
13    003212      m
14    003213      n
15    003214      o

您需要返回数据框,因为R 不是按引用分配的语言。您对lapply 中的i 的分配只是修改i 的本地副本,而不是全局环境中dataList 中的数据框。如果您想修改dataList,您可以用dataList 替换上述表达式中的df.pad,这将导致dataList 被包含修改后的数据帧的新版本覆盖。

【讨论】:

  • ?transform 给我一个关于编程脚本的警告?警告 这是一个旨在以交互方式使用的便利功能。对于编程,最好使用标准的子集算术函数,特别是参数转换的非标准评估可能会产生意想不到的后果。
  • @mtelesha,我相信当您想将变量用作transform 的参数时,警告适用,我们在这里不这样做(例如transform(DF, x=arg_from_my_fun))。
【解决方案2】:

您对列进行了分配,但 a) 没有 return 数据框,b) 您也没有将结果分配给新名称。 (欢迎使用函数式编程。在对象上运行函数不会更改原始对象。)您得到的只是名称:

df1 <- data.frame(person.id = 3200:3214, letter = letters[1:15])
df2 <- data.frame(person.id = 4100:4114, letter = letters[8:22])
df3 <- data.frame(person.id = 4300:4314, letter = letters[10:24])
df4 <- data.frame(person.id = 5500:5514, letter = letters[5:19])
dataList <- list(df1, df2, df3, df4)

library(stringr)
newList <- lapply(dataList, function(i){
  i$person.id <- str_pad(i$person.id, 6, pad = "0"); return(i)
})

> str(newList)
List of 4
 $ :'data.frame':   15 obs. of  2 variables:
  ..$ person.id: chr [1:15] "003200" "003201" "003202" "003203" ...
  ..$ letter   : Factor w/ 15 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ :'data.frame':   15 obs. of  2 variables:
  ..$ person.id: chr [1:15] "004100" "004101" "004102" "004103" ...
  ..$ letter   : Factor w/ 15 levels "h","i","j","k",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ :'data.frame':   15 obs. of  2 variables:
  ..$ person.id: chr [1:15] "004300" "004301" "004302" "004303" ...
  ..$ letter   : Factor w/ 15 levels "j","k","l","m",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ :'data.frame':   15 obs. of  2 variables:
  ..$ person.id: chr [1:15] "005500" "005501" "005502" "005503" ...
  ..$ letter   : Factor w/ 15 levels "e","f","g","h",..: 1 2 3 4 5 6 7 8 9 10 ...

【讨论】:

    【解决方案3】:

    qdapTools包中的pad函数可以做到这一点:

    df1 <- data.frame(person.id = 3200:3214, letter = letters[1:15])
    df2 <- data.frame(person.id = 4100:4114, letter = letters[8:22])
    df3 <- data.frame(person.id = 4300:4314, letter = letters[10:24])
    df4 <- data.frame(person.id = 5500:5514, letter = letters[5:19])
    dataList <- list(df1, df2, df3, df4)
    
    library(qdapTools)
    lapply(dataList, function(x) {x[["person.id"]] <- pad(x[["person.id"]], 6);x})
    

    【讨论】:

      猜你喜欢
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多