我想将函数应用于数据框的每一行。使用apply,结果本身不再是数据框,它看起来更像是列表或矩阵? (我不知道足够的R能够从输出中得知,只是它不是数据帧)
用于将函数应用于数据帧的每一行,返回新数据帧的正确函数是什么?
我想要应用于每一行的功能:
map_uri <- function(request){
ret <- request
uri_stem <- uri_map[uri_map[,1] == request["cs-uri-query"],2]
if(length(uri_stem) > 0){
ret <- request
ret["cs-uri-stem"] <- uri_stem
ret["cs-uri-query"] <- "-"
}
if(request["cs-uri-stem"] == "/index.html"){
ret["cs-uri-stem"] = "/"
}
return(ret)
}
我在尝试什么:
cleansed <- apply(requests, 1, map_uri)
cleansed[,c("cs-uri-query", "cs-uri-stem")]
给了我错误
Fehler in cleansed [,c(“cs-uri-stem”,“cs-uri-query”)]:Indizierung außerhalbderGrenzen
(索引越界)
由于某种原因,结构的变化使得上面的索引错误。
[编辑]
数据使这成为一个有效的例子:
uri_map.tsv http://pastebin.com/XhUuTMqA
uri_map <- read.table("http://pastebin.com/raw/XhUuTMqA", sep="\t", header=FALSE)
输入转换函数的数据:
requests&lt; - read.table(“http://pastebin.com/raw/b7ja4rKn”,sep =“”,header = TRUE)
答案 0 :(得分:15)
你可以使用申请系列,但是,你是对的,结果是matrix
或data.frame
。回到data.frame
。
你的函数需要在列之间返回一致的内容(原始iris
而不是iris[, 1:4]
在下面不起作用,因为iris$Species
这是一个3级因子{{1} }从数字列返回6个数字),这是reproducible有用的地方。下面,我使用了summary
和iris
:
summary
as.data.frame(apply(iris[, 1:4], 2, summary))
as.data.frame(sapply(iris[, 1:4], summary))
答案 1 :(得分:0)
我刚刚实现了这个函数,它将 FUN
作为列表应用于行并将结果连接到 tibble
:
library(magrittr)
lapply_rows <- function(df, return_tibble = TRUE, FUN, ...) {
df_rownames <- rownames(df)
res <- lapply(purrr::transpose(df), FUN = FUN, ...) %>%
purrr::map_depth(2, function(x) {
if (length(x) != 1) {
return(list(x))
} else {
return(x)
}
}) %>%
dplyr::bind_rows()
if (!return_tibble) {
res <- as.data.frame(res)
rownames(res) <- df_rownames
}
return(res)
}
df
由 purrr::transpose(df)
转换为列表列表,其中每个子列表是原始 df
的一行。 FUN
必须返回一个命名列表,它也可以包含长度不为 1 的元素。然后将这些元素包装在 list()
中(类似 data.frame
的对象的列类型也可以是列表)。如果 return_tibble
为 FALSE
,则结果被强制为 data.frame
并设置原始行名。
示例:
df <- lapply_rows(mtcars, FUN = function(row_list) {
row_list$cyl_2 <- row_list$cyl ** 2
row_list$colors <- c("red", "green", "blue")
row_list$sublist <- mtcars[1:5, 1:5]
return(row_list)
})
head(df)
# A tibble: 6 x 14
mpg cyl disp hp drat wt qsec vs am gear carb cyl_2 colors sublist
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <list> <list>
1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 36 <chr [3]> <df[,5] [5 × 5]>
2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 36 <chr [3]> <df[,5] [5 × 5]>
3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 16 <chr [3]> <df[,5] [5 × 5]>
4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 36 <chr [3]> <df[,5] [5 × 5]>
5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 64 <chr [3]> <df[,5] [5 × 5]>
6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 36 <chr [3]> <df[,5] [5 × 5]>
返回 data.frame
的示例:
df2 <- lapply_rows(mtcars, return_tibble = FALSE, FUN = function(row_list) {
row_list$cyl_2 <- row_list$cyl ** 2
row_list$colors <- c("red", "green", "blue")
row_list$sublist <- mtcars[1:5, 1:5]
return(row_list)
})
head(df2)
mpg cyl disp hp drat wt qsec vs am gear carb cyl_2 colors
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 36 red, green, blue
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 36 red, green, blue
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 16 red, green, blue
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 36 red, green, blue
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 64 red, green, blue
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 36 red, green, blue
sublist
Mazda RX4 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
Mazda RX4 Wag 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
Datsun 710 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
Hornet 4 Drive 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
Hornet Sportabout 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
Valiant 21.00, 21.00, 22.80, 21.40, 18.70, 6.00, 6.00, 4.00, 6.00, 8.00, 160.00, 160.00, 108.00, 258.00, 360.00, 110.00, 110.00, 93.00, 110.00, 175.00, 3.90, 3.90, 3.85, 3.08, 3.15
(您可以看到 tibble
更好地处理了 <list>
列)