R for循环或应用于数据表列

时间:2016-05-24 10:19:57

标签: r for-loop dataframe multiple-columns

尝试对数据框中的每一列执行某些操作。不确定使用applyfor(不确定如何忽略apply中的第一列)。

问题1:

为了简单地打印每个名字,我想出了:

for (i in names(dt)){if(str_length(i) < 3) {print(i);print(i)}}

第一列的名称是唯一一个字符串长度为&gt;的名称。 3这就是我使用它的原因。

我尝试使用:

for (i in dt$i){if(str_length(names(i)) < 3) {print(i);print(i)}}
for (i in dt$i){if(str_length(names(dt)) < 3) {print(i);print(i)}}

只需将每列打印两次,但它只是创建了一个空值。

问题2:

我实际上要做什么而不是打印两次;按顺序排列每列:order(-i) ??

然后创建一个子集:head(i, n=500) ??

不确定这是额外步骤还是上述步骤的扩展。然后将其定义为data.frame; dt(i) < data.frame(head(i, n=500)) ...

然后保存该表:write.csv(dt(i), "newfolder/i.csv", row.names = FALSE) - 我认为这将不断覆盖一个名为i.csv的文件,不知道我是如何基于i命名文件的。

也许apply是一种更好的方法,我不确定。

我会欣赏最简单的方法(这样我理解发生了什么)。我只有40列,每行有50,000行,所以它不应该那么慢。

修改

试着更清楚我会添加一个例子:

Name  Math Science PE
David  90    70    25
Tom    100   60    40
John   30    40    100

我希望以3 csv结束,第一个看起来像:

Name Math
Tom  100
David 90

在上述情况下,头部n = 2。此外,csv可以包含其他列,但它们不是必需的。

2 个答案:

答案 0 :(得分:3)

使用您的虚拟数据,我们可以遍历&#34;主题&#34;第2列:n,然后排序,并写出前2个结果:

# dummy data
df <- read.table(text="Name  Math Science PE
David  90    70    25
Tom    100   60    40
John   30    40    100", header = TRUE)


# loop and write csv for top 2 scores
lapply(colnames(df)[2:ncol(df)], function(i){
  res <- df[, c("Name", i)]
  res <- res[order(res[, i], decreasing = TRUE),]
  write.csv(head(res, 2), file = paste0(i, ".csv"))
})

答案 1 :(得分:2)

尝试这样的事情(以mtcars为例):

mtcars[] <- lapply(mtcars, sort)
head(mtcars)

在这里,您可以将每列从最小到最大排序。请注意,每个单独的行都不再有用,因为它不代表特定的单元。你确实得到了你想要的输出。然后,您只需使用head()即可获得所需的条目数。

看看会发生什么:

首先,原始数据的外观如何:

> head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

现在让我们对每一列进行排序:

> mtcars[] <- lapply(mtcars, sort)

输出结果如何:

> head(mtcars, 5)
                   mpg cyl disp hp drat    wt  qsec vs am gear carb
Mazda RX4         10.4   4 71.1 52 2.76 1.513 14.50  0  0    3    1
Mazda RX4 Wag     10.4   4 75.7 62 2.76 1.615 14.60  0  0    3    1
Datsun 710        13.3   4 78.7 65 2.93 1.835 15.41  0  0    3    1
Hornet 4 Drive    14.3   4 79.0 66 3.00 1.935 15.50  0  0    3    1
Hornet Sportabout 14.7   4 95.1 66 3.07 2.140 15.84  0  0    3    1

您还会看到rownames不再提供信息。请确保这是你想要的。要获取新数据帧的最小500行以进行保存,只需使用常规子集,例如df[1:500,]

要保留名称,我们可以生成数据框列表:

newdat <- lapply(mtcars, function(x){
  dat <- data.frame(ind = rownames(mtcars), out = x)
  dat <- dat[order(dat$out),]
})

此处,输出将是包含旧rownames(名为ind)和名为out的有序列的列表。它是一个命名列表,其中每个列表元素对应于原始列的名称。请注意,您可以进一步使用list结构,例如lapply(newdat, head)