创建不等长的数据帧

时间:2011-08-25 19:58:37

标签: r dataframe

虽然数据框列的行数必须相同,但有没有办法创建长度不等的数据框。我没有兴趣将它们保存为列表的单独元素,因为我经常不得不将这些信息作为csv文件发送给人们,这是最简单的数据框架。

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))
cbind(x,y,z)

在上面的代码中,cbind()函数只是回收较短的列,以便它们在每列中都有10个元素。我怎样才能改变长度为2,10和5。

我过去通过以下方式做到了这一点,但效率很低。

  df = data.frame(one=c(rep("one",2),rep("",8)), 
           two=c(rep("two",10)), three=c(rep("three",5), rep("",5))) 

6 个答案:

答案 0 :(得分:26)

对不起,这不完全是你提出的问题,但我认为可能还有另一种方式可以得到你想要的东西。

首先,如果向量是不同的长度,数据不是真正的表格,是吗?如何将其保存到不同的CSV文件?您也可以尝试使用ascii格式来存储多个对象(jsonXML)。

如果您认为数据确实是表格式的,您可以填写NAs:

> x = 1:5
> y = 1:12
> max.len = max(length(x), length(y))
> x = c(x, rep(NA, max.len - length(x)))
> y = c(y, rep(NA, max.len - length(y)))
> x
 [1]  1  2  3  4  5 NA NA NA NA NA NA NA
> y
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

如果您绝对必须使用不相等的列制作data.frame,那么您可能会破坏支票,这是您自己的危险:

> x = 1:5
> y = 1:12
> df = list(x=x, y=y)
> attributes(df) = list(names = names(df),
    row.names=1:max(length(x), length(y)), class='data.frame')
> df
      x  y
1     1  1
2     2  2
3     3  3
4     4  4
5     5  5
6  <NA>  6
7  <NA>  7
 [ reached getOption("max.print") -- omitted 5 rows ]]
Warning message:
In format.data.frame(x, digits = digits, na.encode = FALSE) :
  corrupt data frame: columns will be truncated or padded with NAs

答案 1 :(得分:6)

填充的另一种方法:

na.pad <- function(x,len){
    x[1:len]
}

makePaddedDataFrame <- function(l,...){
    maxlen <- max(sapply(l,length))
    data.frame(lapply(l,na.pad,len=maxlen),...)
}

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))

makePaddedDataFrame(list(x=x,y=y,z=z))

如果您尝试索引不存在的元素,则na.pad()函数会利用R将自动使用NA填充向量的事实。

makePaddedDataFrame()只找到最长的一个并将其余部分填充到匹配的长度。

答案 2 :(得分:4)

要放大@ goodside的答案,你可以做类似

的事情
L <- list(x,y,z)
cfun <- function(L) {
  pad.na <- function(x,len) {
   c(x,rep(NA,len-length(x)))
  }
  maxlen <- max(sapply(L,length))
  do.call(data.frame,lapply(L,pad.na,len=maxlen))
}

(未测试的)。

答案 3 :(得分:3)

这是不可能的。您可以获得的最接近的是使用值NA填充“空”空格。

答案 4 :(得分:0)

我们可以通过用空字符“”填充列来创建包含不等长列的数据框。以下代码可用于创建长度不等的数据框

代码首先找到列表对象的最大列长度,l接下来用“”填充列。这将导致列表的每一列具有相同数量的元素。然后将该列表转换为数据框。

# The list column names
cols <- names(l)

# The maximum column length
max_len <- 0
for (col in cols){
    if (length(l[[col]]) > max_len)
        max_len <- length(l[[col]])
}

# Each column is padded
for (col in cols){
    l[[col]] <- c(l[[col]], rep("", max_len - length(l[[col]])))
}

# The list is converted to data frame
df <- as.data.frame(l)

答案 5 :(得分:-1)

类似的问题:

 coin <- c("Head", "Tail")
toss <- sample(coin, 50, replace=TRUE)

categorize <- function(x,len){
  count_heads <- 0
  count_tails <- 0
  tails <- as.character()
  heads <- as.character()
  for(i in 1:len){
    if(x[i] == "Head"){
      heads <- c(heads,x[i])
      count_heads <- count_heads + 1
    }else {
      tails <- c(tails,x[i])
      count_tails <- count_tails + 1
    }
  }
  if(count_heads > count_tails){
    head <- heads
    tail <- c(tails, rep(NA, (count_heads-count_tails)))
  } else {
    head <- c(heads, rep(NA,(count_tails-count_heads)))
    tail <- tails
  }
  data.frame(cbind("Heads"=head, "Tails"=tail))
}
  

群归类(簸,50)

输出: After the toss of the coin there will be 31 Head and 19 Tail. Then the rest of the tail will be filled with NA in order to make a data frame.