了解适用于数据帧列表

时间:2019-07-24 02:01:37

标签: r list dataframe lapply

我正在清理一组文本文件,当前将它们作为具有相同结构的数据帧列表进行处理。

鉴于文本文件的结构,每个df中最终都有一个不规则的单元格。该单元格包含一个包含列名和值的字符串。我需要提取值并将其分配给新列,然后再进行其他一些重新分配以获得所需的干净dfs。最终,我知道我需要对数据本身做些什么,但是我仍然想弄清楚如何针对这个特定问题在df列表上进行操作。

最小数据示例:

x = data.frame(V1 = c(1, 2, "Column name: 1.18"), V2 = c(1, 2, ""), V3 = c(1, 2, ""),
stringsAsFactors = FALSE)

                 V1 V2 V3
1                 1  1  1
2                 2  2  2
3 Column name: 1.18

list_x = list(x, x)

[[1]]
                 V1 V2 V3
1                 1  1  1
2                 2  2  2
3 Column name: 1.18      

[[2]]
                 V1 V2 V3
1                 1  1  1
2                 2  2  2
3 Column name: 1.18  

我主要使用lapply来清理dfs,但仅用于添加/删除行/列和设置名称。这符合我的预期。

我认为lapply可以用于不规则单元格,但我不理解如何获取dfs列表中的数据。我在单个df上执行的操作不在列表中。我的误解是如何将lapply的输出分配给原始dfs。我已经阅读了有关在dfs列表上进行操作的一些资源和相关问题,但尚未提出解决方案。

我的lapply函数:

list_x = lapply(list_x, function(x) gsub("Column name: ", "", x[3,1]))

[[1]]
[1] "1.18"

[[2]]
[1] "1.18"

我希望使用lapply的赋值可以处理dfs中的数据,但是,它会将每个列表仅分配给gsub的输出,从而消除了其余数据。

这是我的策略,因为这是我在单个df上解决问题时想出了正确的数据结构的方法:

x2 = x
x2[3,1] = gsub("Column name: ", "", x2[3,1])
x2$V4 = 0
x2$V4[3] = as.numeric(x2$V1[3])
x2[3,1] = "3"
x2[x2==""] = 0

  V1 V2 V3   V4
1  1  1  1 0.00
2  2  2  2 0.00
3  3  0  0 1.18

2 个答案:

答案 0 :(得分:0)

如果要创建四列,请在listlapply之间循环,然后从第一列的第三行中提取数字部分,并从已经存在的cbind中提取数字部分通过添加0来添加数据集的列。

lapply(list_x, function(x)  rbind(head(cbind(x, V4 = 0), -1), 
     rep(c(3, 0, as.numeric(gsub("[^.0-9]+", "", x[3, 1]))), c(1, 2, 1)) ))
#[[1]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18

#[[2]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18

或者另一种选择是创建一个函数以应用于list数据帧。

f1 <- function(x) {i1 <- grep("Column name", x$V1)
       v1 <- as.numeric(sub(".*\\s([0-9.]+)$", "\\1", x$V1[i1]))
       x1 <- x[-i1,]
       x1$V4 <- 0
       rbind(x1, list(V1 = 3, V2 = 0, V3 = 0, V4 = v1))
        }
lapply(list_x, f1)
#[[1]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18

#[[2]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18

答案 1 :(得分:0)

如果您能够使其适用于一个数据帧,并且数据帧列表中的每个数据帧都遵循相同的结构,则将其放入一个函数中,并使用lapply将函数应用于列表中的每个数据帧< / p>

apply_fun <- function(x2)  {
    x2[3,1] = sub("Column name: ", "", x2[3,1])
    x2$V4 = 0
    x2$V4[3] = as.numeric(x2$V1[3])
    x2[3,1] = 3
    x2[x2==""] = 0
    x2
}

lapply(list_x, apply_fun)

#[[1]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18

#[[2]]
#  V1 V2 V3   V4
#1  1  1  1 0.00
#2  2  2  2 0.00
#3  3  0  0 1.18